请记住,我将在lat/long对上执行计算,哪种数据类型最适合与MySQL数据库一起使用?
使用MySQL的GIS 空间扩展.
谷歌为使用谷歌地图的"商店定位器"应用程序提供了一个开始完成PHP/MySQL解决方案.在此示例中,它们将lat/lng值存储为"Float",长度为"10,6"
http://code.google.com/apis/maps/articles/phpsqlsearch.html
基本上,它取决于您所在位置所需的精度.使用DOUBLE,你将拥有3.5nm的精度.DECIMAL(8,6)/(9,6)下降到16cm.FLOAT是1.7米......
这个非常有趣的表有一个更完整的列表:http://mysql.rjweb.org/doc.php/latlng:
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
希望这可以帮助.
MySQL的Spatial Extensions是最佳选择,因为您可以使用空间运算符和索引的完整列表.空间索引将允许您非常快速地执行基于距离的计算.请记住,从6.0开始,Spatial Extension仍然不完整.我没有放下MySQL Spatial,只是在你对这个问题做出太多分析之前让你知道陷阱.
如果您严格处理积分并且只处理DISTANCE功能,那么这很好.如果需要使用"多边形","线"或"缓冲点"进行任何计算,则除非使用"关联"运算符,否则空间运算符不会提供精确结果.请参阅21.5.6顶部的警告.诸如包含,内部或相交之类的关系使用MBR,而不是精确的几何形状(即椭圆被视为矩形).
此外,MySQL Spatial中的距离与第一个几何体的距离相同.这意味着如果您使用十进制度数,则您的距离测量值为十进制度数.这将使你很难得到准确的结果,因为你从赤道得到了更好的结果.
当我为ARINC424构建的导航数据库执行此操作时,我进行了大量测试并回顾了代码,我使用了DECIMAL(18,12)(实际上是NUMERIC(18,12)因为它是firebird).
浮点数和双打数据并不精确,可能会导致舍入错误,这可能是一件非常糟糕的事情.我不记得我是否发现任何有问题的真实数据 - 但我相当确定无法准确存储在浮点数或双数据中可能会导致问题
关键是当使用度数或弧度时,我们知道值的范围 - 并且小数部分需要最多的数字.
在MySQL中的空间扩展是一个很好的选择,因为他们遵循的开放GIS几何模型.我没有使用它们,因为我需要保持数据库的可移植性.
取决于您需要的精度.
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
class时,存储坐标的参数顺序必须是POINT(latitude, longitude)
.
有一种用于创建空间索引的特殊语法.
使用SDT的最大好处是您可以访问空间分析功能,例如计算两点之间的距离(ST_Distance
)并确定一个点是否包含在另一个区域内(ST_Contains
).
基于这篇wiki文章 http://en.wikipedia.org/wiki/Decimal_degrees#Accuracy,MySQL中 的相应数据类型是Decimal(9,6),用于将经度和纬度存储在单独的字段中.
使用DECIMAL(8,6)
纬度(90至-90度)和DECIMAL(9,6)
经度(180〜-180度).对于大多数应用程序,小数点后6位.两者都应该"签名"以允许负值.
根据谷歌地图,没有必要走远,最好的是lat和lng的FLOAT(10,6).
我们将oracle数据库中的纬度/经度X 1,000,000存储为NUMBERS,以避免双打出现错误.
鉴于小数点后第6位的纬度/经度是10厘米精度,这就是我们所需要的.许多其他数据库也将lat/long存储到第6个小数位.
从一个完全不同和更简单的角度来看:
如果您依靠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等).
这样您就不必担心索引数字以及与数据类型相关的所有其他问题,这些问题可能会破坏您的坐标.