请记住,我将在lat / long对上执行计算,哪种数据类型最适合与MySQL数据库一起使用?
-
我发现这个链接非常有用:howto-use-mysql-spatial-ext.blogspot.com/2007/11/…它可能有点旧,但它包含一个完整的解释,包括示例。
-
Imho这里的大多数人都不明白会发生什么。一旦应用程序代码触及一个数字,如果使用双精度数(大多数都使用双精度数),则该数字最多变为双精度。然后存储它甚至一百万个小数也不会有任何好处。使用有限数量的小数(例如6)存储它会破坏该精度的一部分,并在每次将其重新写入数据库时??添加累积错误。双重携带大约16个有效数字,可能是所有小数。刮掉其中的10个会随着时间的推移产生累积误差。它是"浮点"的原因。续
-
Cont:当存储从外部源获取的图形时,6位小数可能没问题,未经改变并且是第一次 - 作为源材料。但是如果对它进行一次计算,并再次存储它,通过强制执行特定的十进制格式来删除部分精度是愚蠢的。仅在服务器内部执行计算可能不同(服务器可能使用或不使用除内部之外的其他内容),并且在应用计算中使用比双倍更差的数字表示会降低对存储精度的需求。
-
Cont:如果服务器存储的数字具有更高的精度,尽管声称"9.6"(我不知道它是否确实如此),那么这一切都不重要,而且格式纯粹是方便的事情 - 几乎没有处理精确问题。但是如果服务器实际上使用该格式将任何数字舍入为6位小数精度,我不会感到惊讶。
-
Cont:最后:对于lat,lon,第6个小数是一个捕获到ca的问题。 11厘米的网格。每次读取(触摸),再次计算和存储,小数点后6位,都会有新的捕捉(=累积误差)。如果所有错误都发生在同一方向,则会出现很大的错误。如果对它进行临时乘法(例如,按比例放大,然后减去并缩小),它可能会变得更大。如果没有良好的rason,请不要丢弃精度!
-
@Stormwind - 不,反复提取和存储(没有任何算术)不会每次(可能一次)"累积"错误。此声明适用于所有数字数据类型。
-
(至少在MySQL中),DECIMAL(9.6)被准确存储。正常的阅读和写作不涉及价值的腐败。
-
@Rick James确实如此,但Q说"请记住我将在纬度/长度对上执行计算"......这里:将db存储为整数。从中获取1(一个很好的源值)。计算/扩展51%,向数据库写入1.51(假设它存储1000个小数 - 无关紧要)。重新获取该值,现在得到2.添加PI / 2(1.5707963267948966)并写入3.5707963267948966。获取,现在你得到4.但是在他的阶段更准确的值将是3.0807963267948963。等等。与6位小数相同,它只发生在第6位。如果数据库以这种方式工作,则精度将随着时间的推移而丢失。
-
@Stormwind -"计算"可能是"距离"的一个。即使使用Haversine公式,精度也足以找到"最近的10个星巴"。
-
@Stormwind - 另一项计算实验......拿出一长串美元&美分,每个到最近的美元,添加。现在与精确的总和进行比较。您可能会惊讶于舍入值的总和与精确值的接近程度。最大错误是N / 2美元。但结果的分布是钟形曲线,标准偏差为(IIRC)sqrt(N / 12)。
-
@Stormwind - 你对浮动计算的积累方式是正确的。我的主张是他们没有正常的lat / lng使用。
-
没错,这完全取决于使用情况。有一个相当不错的比喻:采用一个32位游戏物理引擎(7个重要)并做小动作接近(0,0,0) - 一切顺利,运动平稳。现在尝试在(100000,0,0)进行相同的运动 - 不要去。对象永远不会离开它的位置,而不是百万次迭代,或者它将需要大而难看的跳跃。如果计算对大值重复进行小的调整,结果可能会"挂起"。大数值可能会把你带到地狱:-)。因此,一种选择是将数字空间移近零。
-
@Codebeef我注意到你已经回滚了ajreal编辑。然而,我觉得拥有一致的复数更好,所以我部分地重新应用了修改。如果您希望同时具有复数(纬度/经度),我会让您更新它。
-
@ToolmakerSteve - 我认为我们不同意任何事情?作为计算的一部分,我正在反复写入一个精度有限的数据库(小数点后6位!)。一个(相当夸张的)例子是开始计算新的一天 - 每天加1并保持在头部。但是每周五轮到最接近的10 [=写入精度有限的数据库],写入,在星期六获取并继续向获取的数据添加。在年底,你将累积540天:-)。因为7,17,27等可以达到10,20,30等。我完全同意你保持最高精度的原始数据。
-
@ToolmakerSteve - 承认我是偏执狂。对我来说,"可能"几乎与"不可避免"相同。示例:缓冲区溢出从未打算过,但我们已经看过它们40年了,因为它们是可能的。但请注意:原始Q表示"执行计算",这是一个非常圆的陈述。我们不知道这意味着什么。对我来说,可能有多个db r / w。如果它以60%的写入速度向西(在11厘米网格中)捕捉到东部40%......(无论CPU有多精确)并且你做了1000次......为什么邀请它? Np,您的索赔也是有效的 - 这取决于! :-)
-
@Stormwind - 啊,我只是仔细阅读你说的话。我现在看到了你的观点并同意:如果某人以总是四位数的方式读取/写入地理数据,他们很快就会遇到重大的累积错误。我已经习惯于只指定"浮动",我忘记了指定#数字的选项。它的好处是警告人们不要指定#数字,只需选择浮点数(?26位精度)或双精度(大量精度,成本2倍内存),除非他们理解限制数字的后果。 (我删除了之前的所有评论,因为它们只会让人感到困惑。)
使用MySQL的GIS空间扩展。
-
您是否有任何其他链接到示例或任何其他信息,以了解如何最好地开始使用它们?
-
MYSQL Spatial是一个不错的选择,但仍然有很大的限制和警告(截至6)。请看下面我的答案......
-
@James Schek是对的。此外,MySQL使用欧几里德几何进行所有计算,因此它不代表lat / lng的真实用例。
-
仅供参考; Mysql仅支持带有* .myisam表的空间索引,即ISAM引擎。链接:dev.mysql.com/doc/refman/5.0/en/creating-spatial-indexes.html
-
最后看看这篇文章的更新部分:mysqlserverteam.com/mysql-5-7-and-gis-an-example
谷歌为使用谷歌地图的"商店定位器"应用程序提供了一个开始完成PHP / MySQL解决方案。在此示例中,它们将lat / lng值存储为"Float",长度为"10,6"
http://code.google.com/apis/maps/articles/phpsqlsearch.html
-
Google显然不了解FLOAT规范的工作原理:FLOAT(10,6)为坐标的整数部分留下4位数字。不,符号不计 - 来自(未)签名属性。
-
但是如果你需要存储来自[0,180]的整数部分值应该更加足够,对吧?
-
@AlixAxel我认为谷歌知道它在做什么。因为它声明:"使用Google地图的当前缩放功能,您应该只需要小数点后的6位精度。这将使字段存储小数点后的6位数,加上小数点前最多4位数,例如 - 123.456789度。"如果选中unsigned,则模式为1234,567890。所以没问题。
-
@ 1.44mb:1234?这不是一个有效的坐标,我不遵循......
-
@AlixAxel他正在计算序列中的数字;不使用实际坐标...
-
@AndrewEllis:我的观点是这个标志不算数。
-
对Laravel使用数据类型Double
-
我知道我迟到了(2年),但我相信@ 1.44mb是正确的。
-
根据MySql:"MySQL允许非标准语法:FLOAT(M,D)...这里,(M,D)意味着值可以存储最多M个数字,其中D个数字可能在小数点后面例如,定义为FLOAT(7,4)的列在显示时将显示为-999.9999。"使用此示例,您只需要FLOAT(9,6)来存储coord -179.999999。
-
使用float而不是Double会导致大约1-2米的不准确。只是自己测试一下,它炸毁了我的整个应用程序。现在切换到双倍。
-
在MySQL中,'符号'不需要数字。所以(10,6)在整数方面是过度的。 (这不重要,因为4位需要2个字节,3位数也是如此。)
-
@BenDavison - 由于float只有大约7个"有效"数字,所以-179.999999完全被破坏-180. -179.99999变成大约-179.99998474,因为IEEE-754的Float中只有24位精度。
基本上,它取决于您所在位置所需的精度。使用DOUBLE,你将拥有3.5nm的精度。 DECIMAL(8,6)/(9,6)下降到16cm。 FLOAT是1.7米......
这个非常有趣的表有一个更完整的列表:http://mysql.rjweb.org/doc.php/latlng:
1 2 3 4 5 6 7 8 9 10 11 12
| Datatype Bytes Resolution
Deg *100 (SMALLINT) 4 1570 m 1.0 mi Cities
DECIMAL(4,2)/(5,2) 5 1570 m 1.0 mi Cities
SMALLINT scaled 4 682 m 0.4 mi Cities
Deg *10000 (MEDIUMINT) 6 16 m 52 ft Houses /Businesses
DECIMAL(6,4)/(7,4) 7 16 m 52 ft Houses /Businesses
MEDIUMINT scaled 6 2.7 m 8.8 ft
FLOAT 8 1.7 m 5.6 ft
DECIMAL(8,6)/(9,6) 9 16cm 1/2 ft Friends in a mall
Deg *10000000 (INT) 8 16mm 5/8 in Marbles
DOUBLE 16 3.5nm ... Fleas on a dog |
希望这可以帮助。
-
我需要写一篇关于帖子内容的建设性的,详细的评论,所以我会说,在观察Rick James网站提供的准确度表时,我对于"狗跳蚤"的分辨率描述感到有些好笑。觉得值得称赞。从技术上讲,这是一个有用的描述,帮助我决定在存储坐标时使用什么数据类型来测量两个地址之间的距离,@Simon,我要感谢你的分享。
-
有关精度stackoverflow.com/a/16743805/722135的更多信息
MySQL的Spatial Extensions是最佳选择,因为您可以使用空间运算符和索引的完整列表。空间索引将允许您非常快速地执行基于距离的计算。请记住,从6.0开始,Spatial Extension仍然不完整。我没有放下MySQL Spatial,只是在你对这个问题走得太远之前让你知道陷阱。
如果您严格处理积分并且只处理DISTANCE功能,那么这很好。如果需要使用"多边形","线"或"缓冲点"进行任何计算,则除非使用"关联"运算符,否则空间运算符不会提供精确结果。请参阅21.5.6顶部的警告。诸如包含,内部或相交之类的关系使用MBR,而不是精确的几何形状(即,椭圆被视为矩形)。
此外,MySQL Spatial中的距离与第一个几何体的距离相同。这意味着如果您使用十进制度数,则您的距离测量值为十进制度数。这将使你很难得到准确的结果,因为你从赤道得到了更好的结果。
-
重述:MySQL Spatial Extensions不适合计算由lat / long表示的地球表面上的点之间的大圆距离。它们的距离函数等仅适用于笛卡尔坐标,平面坐标。
当我为ARINC424构建的导航数据库执行此操作时,我进行了大量测试并回顾了代码,我使用了DECIMAL(18,12)(实际上是NUMERIC(18,12)因为它是firebird)。
浮点数和双打数据并不精确,可能会导致舍入错误,这可能是一件非常糟糕的事情。我不记得我是否发现任何有问题的真实数据 - 但我相当确定无法准确存储在浮点数或双数据中可能会导致问题
关键是当使用度数或弧度时,我们知道值的范围 - 并且小数部分需要最多的数字。
MySQL Spatial Extensions是一个很好的选择,因为它们遵循OpenGIS几何模型。我没有使用它们,因为我需要保持数据库的可移植性。
-
谢谢,这很有帮助。从2008年开始意识到它已经是8年前的所有这些问题和答案,感觉很奇怪。
-
@TheSexiestManinJamaica - 在IEEE 754-1985之前,计算机浮点硬件很混乱。甚至在机器上a*b不等于b*a(对于某些值)。有许多例子有点像:2+2 = 3.9999。该标准清理了很多混乱,几乎每一件硬件和软件都"迅速"采用。所以,这个讨论是有效的,不仅仅是自2008年以来,而是三分之一世纪。
取决于您需要的精度。
1 2 3 4 5 6 7 8 9 10 11 12
| Datatype Bytes resolution
------------------ ----- --------------------------------
Deg *100 (SMALLINT) 4 1570 m 1.0 mi Cities
DECIMAL(4,2)/(5,2) 5 1570 m 1.0 mi Cities
SMALLINT scaled 4 682 m 0.4 mi Cities
Deg *10000 (MEDIUMINT) 6 16 m 52 ft Houses /Businesses
DECIMAL(6,4)/(7,4) 7 16 m 52 ft Houses /Businesses
MEDIUMINT scaled 6 2.7 m 8.8 ft
FLOAT 8 1.7 m 5.6 ft
DECIMAL(8,6)/(9,6) 9 16cm 1/2 ft Friends in a mall
Deg *10000000 (INT) 8 16mm 5/8 in Marbles
DOUBLE 16 3.5nm ... Fleas on a dog |
来自:http://mysql.rjweb.org/doc.php/latlng
总结一下:
-
最精确的可用选项是DOUBLE。
-
最常见的类型是DECIMAL(8,6)/(9,6)。
从MySQL 5.7开始,考虑使用空间数据类型(SDT),特别是POINT来存储单个坐标。在5.7之前,SDT不支持索引(当表类型为MyISAM时,5.6除外)。
注意:
-
使用POINT类时,存储坐标的参数顺序必须为POINT(latitude, longitude)。
-
有一种用于创建空间索引的特殊语法。
-
使用SDT的最大好处是您可以访问空间分析功能,例如计算两点之间的距离(ST_Distance)并确定一个点是否包含在另一个区域内(ST_Contains)。
-
你复制了上一个答案的粘贴部分,并用创建该表的人不推荐的东西"总结":«如何分区?好吧,MySQL非常挑剔。所以FLOAT / DOUBLE出局了。 DECIMAL已经结束了。所以,我们坚持一些kludge。基本上,我们需要将Lat / Lng转换为某个大小的INT并使用PARTITION BY RANGE。» AND« FLOAT有24位有效位; DOUBLE有53.(它们不适用于PARTITIONing,但是为了完整性而包括在内。通常人们使用DOUBLE而不知道它有多大,以及需要多少空间。)»离开你写的SDT部分。
-
@Armfoot如果你看一下编辑的时间,那就是从我那里复制的另一个答案。并不重要:我看到Stack Overflow更像是"未来我的笔记"。
-
不,他没有从你那里复制,他就像你在2014年引用的链接一样粘贴了桌子(你的帖子是从2015年开始)。顺便说一下,当你链接空间数据类型时,我认为你拼错了"特殊"。你写的这部分对于想要开始使用它们的人来说实际上是有用的,如果你添加一些像CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g)) ENGINE=MyISAM;这样的例子和关于SDT限制的警告,正如詹姆斯提到的那样,也许你的答案在帮助其他人时会更简洁和准确还有......
-
对狗的精确跳蚤的upvote!
-
@ Gajus - 我很荣幸你们两个人找到了我的文件! (不,我不知道跳蚤有多大,但我觉得这会引起别人的注意。)
-
使用POINT类时,存储坐标的参数顺序必须为POINT(经度/ X,纬度/ Y)。
-
@AndreyP - 似乎POINT()将X和Y存储在DOUBLE中。 POINT的大小进一步证实了这一点。跳蚤!
基于这篇wiki文章
http://en.wikipedia.org/wiki/Decimal_degrees#Accuracy
MySQL中适当的数据类型是Decimal(9,6),用于存储经度和纬度
单独的领域。
使用DECIMAL(8,6)表示纬度(90到-90度),DECIMAL(9,6)表示经度(180到-180度)。对于大多数应用程序,小数点后6位。两者都应该"签名"以允许负值。
-
DECIMAL类型用于不接受floor/ceil的财务计算。普通float明显优于DECIMAL。
-
@Kondybas - 由于数据库中的主要成本是获取行,因此浮点数和小数之间的性能差异不应该是一个问题。
根据谷歌地图,没有必要走远,最好的是lat和lng的FLOAT(10,6)。
我们将oracle数据库中的纬度/经度X 1,000,000存储为NUMBERS,以避免双打出现错误。
鉴于小数点后第6位的纬度/经度是10厘米精度,这就是我们所需要的。许多其他数据库也将lat / long存储到第6个小数位。
-
如果你有大量的数据,乘以一些大数字(如一百万)是很好的,因为整数运算(例如索引检索)要比浮点数快得多。
-
@KaitlinDuckSherwood - 位是比特 - 我不知道32位浮点数对于检索(索引或其他)比32位整数更慢的原因。即使是浮动数学这些天也很快就成了一个非问题。不过,我同意将隐含乘数与整数一起使用的注释:它最大化了32位的精度。随着技术的进步,一点未来的发展。
从一个完全不同和更简单的角度来看:
-
如果您依靠Google来显示您的地图,标记,多边形等等,那么请让Google完成计算!
-
您可以在服务器上保存资源,只需将纬度和经度一起存储为单个字符串(VARCHAR),例如:" - 0000.0000001,-0000.000000000000001"(长度为35,如果数字的小数位数超过7位则会得到圆形);
-
如果谷歌每个号码返回的小数位数超过7位数,那么无论如何你都可以将这些数据存储在你的字符串中,以防你以后想要检测一些逃亡或微生物;
-
你可以使用它们的距离矩阵或它们的几何库来计算某些区域的距离或检测点,调用就像这样简单:google.maps.geometry.poly.containsLocation(latLng, bermudaTrianglePolygon))
-
您可以使用许多"服务器端"API(使用Google Maps API,使用Python,Ruby on Rails,PHP,CodeIgniter,Laravel,Yii,Zend Framework等)。
这样您就不必担心索引数字以及与数据类型相关的所有其他问题,这些问题可能会破坏您的坐标。
-
不好。 OP表示他将对lat / lng对进行计算 - 你的答案排除了这一点
-
@Yarin这是一个很受欢迎的问题,其中一些(或很多)人只需要根据自己的需求来解答如何存储坐标(很多人可能只使用Google地图)。你的downvote暗示这个答案可能无法帮助他们......通过将坐标存储在一个字符串中,他们将确切地知道提供给他们的原始值(例如:Google),如果他们决定进化他们的话,他们会在以后帮助他们自己的应用程序并对它们执行计算。那时,他们仍然会拥有原始的原始数据,因为他们没有弄乱转换。
取决于你的应用程序,我建议使用FLOAT(9,6)
空间键将为您提供更多功能,但在生产基准测试中,浮点数比空间键快得多。 (AVG中0,01 VS 0,001)
虽然它并非对所有操作都是最佳的,但如果您正在制作地图图块或使用大量标记(点)只使用一个投影(例如墨卡托,如谷歌地图和许多其他滑动地图框架预期),我找到了什么我称之为"Vast Coordinate System"非常非常方便。基本上,你以某种方式存储x和y像素坐标 - 放大 - 我使用缩放级别23.这有几个好处:
-
您只需执行一次昂贵的lat / lng到mercator像素转换,而不是每次处理该点
-
从给定缩放级别的记录中获取切片坐标需要一次右移。
-
从记录中获取像素坐标需要一个右移和一个按位AND。
-
这些转换非常轻巧,在SQL中实现它们是切实可行的,这意味着您可以执行DISTINCT,每个像素位置只返回一条记录,这将减少后端返回的数字记录,这意味着更少的处理前端。
我在最近的博客文章中谈到了这一切:
Optimizing Map Tile Generation
我对一些答案/评论感到非常惊讶。
为什么有人愿意自愿"预先降低"精度,然后再对更糟糕的数字进行计算呢?听起来最愚蠢。
如果源具有64位精度,那么自愿将比例缩小到例如是愚蠢的。 6位小数,并将精度限制为最多9个重要的数字(通常建议的十进制9.6格式)。
当然,可以使用源材料具有的精度来存储数据。降低精度的唯一原因是存储空间有限。
-
以原始精度存储源图
-
在计算发生的精度中存储从源计算的数据(例如,如果应用程序代码使用双精度数,则将结果存储为双精度数)
十进制9.6格式导致对齐网格现象。这应该是最后一步,如果它完全发生的话。
我不会邀请积累的错误到我的巢。
-
因为大多数GPS工具和应用程序仅精确到小数点后6位。毫无意义地将数据存储到比工具可以测量的精度更高的精度gis.stackexchange.com/questions/8650/…
-
@Yarin确实如此,但你谈的是测量和GPS,问题中没有提到。肯定存在更准确的数字。但让我们考虑GPS;说一个64位浮点数的源数据集,已经包含不准确性。 6位小数意味着将纬度捕捉到最接近的11厘米。因此,现在只存储数据(小数点后6位),你可以打开潜在的22厘米不准确度(如果最初也是11厘米)。很可能,可能要进行64位计算,之后可能存储第3次 - 现在是33厘米的不准确窗口,+ -16厘米。听起来很蠢,imho。
-
@Stormwind - 如何存储1/3的结果???
-
@Rick James我可能会把它存储为64位,即。 0.3333333333333333。我们谈地理数据吧?在通常测量物体的情况下,"1/3"很少出现,并且具有合理的精度。
MySQL为所有浮点数使用double ...
所以使用double类型。在大多数情况下,使用float会导致不可预测的舍入值
-
MySQL在Double中执行操作。 MySQL允许您将数据存储为4字节float或8字节Double。因此,将表达式存储到float列时可能会丢失精度。
PostGIS中的空间函数比MySQL空间函数中的空间函数功能更强大(即不受BBOX操作限制)。看看:链接文字
TL; DR
如果你不是在NASA /军队工作而不是制造飞机导航系统,请使用FLOAT(8,5)。
要完全回答您的问题,您需要考虑以下几点:
格式
-
度分秒:40°26'46"N 79°58'56"W
-
度十进制分钟:40°26.767'N 79°58.933'W
-
十进制度1:40.446°N 79.982°W
-
十进制度2:-32.60875,21.27812
-
其他一些自制格式?没有人禁止您制作自己的以家庭为中心的坐标系统,并将其存储为距您家的航向和距离。这可能对您正在处理的一些特定问题有意义。
所以答案的第一部分是 - 您可以以应用程序使用的格式存储坐标,以避免来回不断的转换并进行更简单的SQL查询。
很可能您使用谷歌地图或OSM来显示您的数据,而GMaps使用"十进制度数2"格式。因此,以相同的格式存储坐标会更容易。
精确
然后,您想要定义所需的精度。当然你可以存储像"-32.608697550570334,21.278081997935146"这样的坐标,但你有没有关心导航到点的毫米?如果你不是在美国国家航空航天局工作而不是做卫星或火箭或飞机轨迹,你应该没有几米精度。
常用格式是点后5位数,精度为50cm。
示例:X,21.2780818和X之间的距离为1厘米,21.2780819。因此,点后7位数字给你1 / 2cm精度,点后5位数将给你1/2米精度(因为不同点之间的最小距离是1米,因此舍入误差不能超过它的一半)。对于大多数民用目的来说应该足够了。
度十进制分钟格式(40°26.767'N 79°58.933'W)为您提供与点后5位数完全相同的精度
节省空间的存储
如果您选择了十进制格式,那么您的坐标是一对(-32.60875,21.27812)。显然,2 x(符号为1位,度为2位,指数为5位)就足够了。
所以在这里我想支持Alix Axel的评论说Google建议将它存储在FLOAT(10,6)中是非常多的,因为主要部分不需要4位数(因为符号是分开的,纬度是有限的到90和经度限制为180)。您可以轻松地将FLOAT(8,5)用于1 / 2m精度或FLOAT(9,6)用于50 / 2cm精度。或者您甚至可以将lat和long存储在分离的类型中,因为FLOAT(7,5)足以用于lat。请参阅MySQL float类型参考。它们中的任何一个都将像普通的FLOAT一样,无论如何都等于4个字节。
通常空间现在不是问题,但如果你想出于某种原因真的优化存储(免责声明:不做预优化),你可以压缩lat(不超过91 000值+符号)+ long(no超过181 000个值+符号)到21位,明显小于2xFLOAT(8个字节== 64位)
纬度范围从-90到+90(度),所以DECIMAL(10,8)就可以了
经度范围从-180到+180(度),所以你需要DECIMAL(11,8)。
注意:第一个数字是存储的总位数,第二个数字是小数点后面的数字。
简而言之:lat DECIMAL(10, 8) NOT NULL, lng DECIMAL(11, 8) NOT NULL
Lat Long计算需要精度,因此请使用某种类型的十进制类型,并使精度至少比存储的数字高2,以便执行数学计算。我不知道我的sql数据类型,但在SQL服务器中,人们经常使用float或real而不是decimal,并且遇到麻烦,因为这些是估计的数字而不是真正的数字。因此,只需确保您使用的数据类型是真正的十进制类型而不是浮动十进制类型,您应该没问题。
-
float和decimal类型都有它们的位置。根据经验,浮点数表示物理变量,小数表示可数实体(主要是金钱)。我不明白你为什么喜欢lat / long的十进制数
-
我也认为漂浮对于纬度/长度是好的。至少在SQL Server上(4字节,7位)。
-
漂浮不准确估计,一个纬度的精确湖是致命的!它可以指向你在地球上一个完全不同的地方。
-
float数据类型的最大错误足够低,这应该不是问题。我的意思是,无论如何,您必须意识到两种实现的错误乘法/累积。
-
@HLGEM - 舍入到一些小数位也让你在地球上的另一个地方。问题是这个不同的地点是否如此接近以至于无关紧要。
FLOAT应该为您提供所需的所有精度,并且比将每个坐标存储为字符串等更好地用于比较函数。
如果您的MySQL版本早于5.0.3,则可能需要注意某些浮点比较错误。
Prior to MySQL 5.0.3, DECIMAL columns store values with exact precision because they are represented as strings, but calculations on DECIMAL values are done using floating-point operations. As of 5.0.3, MySQL performs DECIMAL operations with a precision of 64 decimal digits, which should solve most common inaccuracy problems when it comes to DECIMAL columns
-
您需要一个真实的纬度/经度坐标数据类型,以便于数学运算。想象一下这样的便利,比如"从距离(store.location,mylocation)<5英里的商店中选择*"
-
以前没有听说过空间扩展,这听起来非常方便,之前曾在一个继承的应用程序上做了很多与地理相关的计算,必须检查出来。
-
@ConroyP - 否。该引用指出DECIMAL由于使用浮动实现而导致(5.0.3之前)某些错误。