当前位置:  开发笔记 > 后端 > 正文

在MySQL数据库中存储纬度/经度时使用的理想数据类型是什么?

如何解决《在MySQL数据库中存储纬度/经度时使用的理想数据类型是什么?》经验,为你挑选了11个好方法。

请记住,我将在lat/long对上执行计算,哪种数据类型最适合与MySQL数据库一起使用?



1> Kirk Strause..:

使用MySQL的GIS 空间扩展.


您是否有任何其他链接到示例或任何其他信息,以了解如何最好地开始使用它们?
MYSQL Spatial是一个不错的选择,但仍然有很大的限制和警告(截至6).请看下面我的答案......

2> Ted Avery..:

谷歌为使用谷歌地图的"商店定位器"应用程序提供了一个开始完成PHP/MySQL解决方案.在此示例中,它们将lat/lng值存储为"Float",长度为"10,6"

http://code.google.com/apis/maps/articles/phpsqlsearch.html


@AlixAxel我认为谷歌知道它在做什么.因为它指出:"_With谷歌地图目前的缩放能力,您只需要精确6位数字的小数点后这将让域存储小数点后6位数字,以及多达4位小数之前,如*.*-123.456789**degrees._".如果选中无符号,则模式将为**1234,567890**.所以没问题.
@AlixAxel他正在计算序列中的数字; 不使用实际坐标...
Google显然不了解FLOAT规范的工作原理:`FLOAT(10,6)`为坐标的整数部分留下4位数.不,符号不计 - 来自(未)签名属性.
使用Laravel的数据类型"Double"
但是如果你需要存储来自[0,180]的整数部分值应该更加足够,对吧?

3> Simon..:

基本上,它取决于您所在位置所需的精度.使用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

希望这可以帮助.


我需要针对帖子的内容写一篇建设性的详细评论,所以我要说的是,在观察Rick James网站提供的准确度表的同时,我对解决方案描述“狗跳蚤”感到很高兴,并且感到值得荣誉。从技术上讲,这是一个有用的描述,它帮助我决定了在存储用于测量两个地址之间距离的坐标时要使用哪种数据类型,@ Simon,感谢您的分享。

4> James Schek..:

MySQL的Spatial Extensions是最佳选择,因为您可以使用空间运算符和索引的完整列表.空间索引将允许您非常快速地执行基于距离的计算.请记住,从6.0开始,Spatial Extension仍然不完整.我没有放下MySQL Spatial,只是在你对这个问题做出太多分析之前让你知道陷阱.

如果您严格处理积分并且只处理DISTANCE功能,那么这很好.如果需要使用"多边形","线"或"缓冲点"进行任何计算,则除非使用"关联"运算符,否则空间运算符不会提供精确结果.请参阅21.5.6顶部的警告.诸如包含,内部或相交之类的关系使用MBR,而不是精确的几何形状(即椭圆被视为矩形).

此外,MySQL Spatial中的距离与第一个几何体的距离相同.这意味着如果您使用十进制度数,则您的距离测量值为十进制度数.这将使你很难得到准确的结果,因为你从赤道得到了更好的结果.


重述:MySQL Spatial Extensions不适合计算由lat/long表示的地球表面上的点之间的大圆距离.它们的距离函数等仅适用于笛卡尔坐标,平面坐标.

5> Richard Harr..:

当我为ARINC424构建的导航数据库执行此操作时,我进行了大量测试并回顾了代码,我使用了DECIMAL(18,12)(实际上是NUMERIC(18,12)因为它是firebird).

浮点数和双打数据并不精确,可能会导致舍入错误,这可能是一件非常糟糕的事情.我不记得我是否发现任何有问题的真实数据 - 但我相当确定无法准确存储在浮点数或双数据中可能会导致问题

关键是当使用度数或弧度时,我们知道值的范围 - 并且小数部分需要最多的数字.

在MySQL中的空间扩展是一个很好的选择,因为他们遵循的开放GIS几何模型.我没有使用它们,因为我需要保持数据库的可移植性.


谢谢,这很有帮助.从2008年开始意识到它已经是8年前的所有这些问题和答案,感觉很奇怪.

6> Gajus..:

取决于您需要的精度.

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除外).

注意:

使用POINTclass时,存储坐标的参数顺序必须是POINT(latitude, longitude).

有一种用于创建空间索引的特殊语法.

使用SDT的最大好处是您可以访问空间分析功能,例如计算两点之间的距离(ST_Distance)并确定一个点是否包含在另一个区域内(ST_Contains).


对狗的精确跳蚤的upvote!
你复制上一个答案的粘贴部分,并用创建该表**的人**推荐的东西"总结"**:«如何分区?好吧,MySQL非常挑剔.所以FLOAT/DOUBLE出局了.DECIMAL已经结束了.所以,我们坚持一些kludge.基本上,我们需要将Lat/Lng转换为某个大小的INT并使用PARTITION BY RANGE.»和«FLOAT有24个有效位; DOUBLE有53.(它们不适用于PARTITIONing但是为了完整而包括在内.**通常人们使用DOUBLE而没有意识到它是多大的**,以及需要多少空间.)»只需离开SDT部分你中写道.

7> saeed khalaf..:

基于这篇wiki文章 http://en.wikipedia.org/wiki/Decimal_degrees#Accuracy,MySQL中 的相应数据类型是Decimal(9,6),用于将经度和纬度存储在单独的字段中.



8> Alex Holsgro..:

使用DECIMAL(8,6)纬度(90至-90度)和DECIMAL(9,6)经度(180〜-180度).对于大多数应用程序,小数点后6位.两者都应该"签名"以允许负值.



9> Mariano Pein..:

根据谷歌地图,没有必要走远,最好的是lat和lng的FLOAT(10,6).



10> 小智..:

我们将oracle数据库中的纬度/经度X 1,000,000存储为NUMBERS,以避免双打出现错误.

鉴于小数点后第6位的纬度/经度是10厘米精度,这就是我们所需要的.许多其他数据库也将lat/long存储到第6个小数位.


如果你有大量数据,乘以一些大数字(如一百万)是很好的,因为整数运算(例如索引检索)比浮点数快得多.

11> Armfoot..:

从一个完全不同和更简单的角度来看:

如果您依靠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等).

这样您就不必担心索引数字以及与数据类型相关的所有其他问题,这些问题可能会破坏您的坐标.


@Yarin这是一个很受欢迎的问题,其中一些(或很多)人只需要根据自己的需求来解答如何存储坐标(很多人可能只使用Google地图).你的downvote暗示这个答案可能无法帮助他们......通过将坐标存储在一个字符串中,他们将确切地知道提供给他们的原始值(例如:Google),如果他们决定进化他们的话,他们会在以后帮助他们自己的应用程序并对它们执行计算.那时,他们仍然会拥有原始的原始数据,因为他们没有弄乱转换.
推荐阅读
php
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有