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


当前回答

基本上,这取决于你需要的定位精度。使用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的空间扩展是最好的选择,因为你有空间操作符和索引的完整列表。空间索引允许您非常快速地执行基于距离的计算。请记住,作为6.0,空间扩展仍然是不完整的。我并不是在写MySQL Spatial,只是让你在深入了解它之前知道它的缺陷。

如果你严格地处理点,而只是DISTANCE函数,这是可以的。如果需要使用polygon、Lines或Buffered-Points进行任何计算,除非使用“related”操作符,否则空间操作符不会提供准确的结果。请参阅21.5.6顶部的警告。关系,如包含,内部,或交叉使用MBR,而不是确切的几何形状(即椭圆被视为矩形)。

此外,MySQL Spatial中的距离与第一个几何图形的单位相同。这意味着如果你使用的是十进制度数,那么你的距离测量就是十进制度数。当你离赤道越来越远时,这将使你很难得到准确的结果。

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

存储Lat Long值的理想数据类型是十进制(9,6)

这是在大约10cm的精度,而只使用5字节的存储。

例如:CAST(123.456789 as decimal(9,6))

基本上,这取决于你需要的定位精度。使用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

博士TL;

如果你不是在NASA /军队工作,也不是制造飞机导航系统,请使用FLOAT(8,5)。


要完整地回答你的问题,你需要考虑以下几点:

格式

度分秒:40°26′46″N 79°58′56″W 十进制分:北纬40°26.767′,西经79°58.933′ 十进制度数1:40 .446°N 79.982°W 十进制度数2:-32.60875,21.27812 其他的自制格式?没有人禁止你制作自己的以家庭为中心的坐标系统,并将其存储为标题和离家的距离。对于您正在处理的某些特定问题,这可能是有意义的。

因此,答案的第一部分将是-您可以以应用程序使用的格式存储坐标,以避免常量来回转换,并进行更简单的SQL查询。

大多数情况下,您使用谷歌Maps或OSM来显示数据,而gmap使用“十进制2”格式。所以用相同的格式存储坐标会更容易。

精度

然后,您需要定义所需的精度。当然,您可以存储诸如“-32.608697550570334,21.278081997935146”这样的坐标,但在导航到点时,您是否关心过毫米?如果你不是在NASA工作,也不是在研究卫星、火箭或飞机的轨迹,你应该可以接受几米的精度。

常用的格式是圆点后面加5位数字,这样可以得到50cm的精度。

例如:X 21.2780818与X 21.2780819之间有1cm的距离。所以点号后面有7个数字可以得到1/2cm的精度,点号后面有5个数字可以得到1/2米的精度(因为不同点之间的最小距离是1m,所以舍入误差不能超过它的一半)。对于大多数民用目的来说,这应该足够了。

度十进制分钟格式(40°26.767′N 79°58.933′W)的精度与点后5位数字完全相同

空间存储

如果您选择了十进制格式,那么您的坐标是一对(-32.60875,21.27812)。显然,2 x(1位表示符号,2位表示度,5位表示指数)就足够了。

So here I'd like to support Alix Axel from comments saying that Google suggestion to store it in FLOAT(10,6) is really extra, because you don't need 4 digits for main part (since sign is separated and latitude is limited to 90 and longitude is limited to 180). You can easily use FLOAT(8,5) for 1/2m precision or FLOAT(9,6) for 50/2cm precision. Or you can even store lat and long in separated types, because FLOAT(7,5) is enough for lat. See MySQL float types reference. Any of them will be like normal FLOAT and equal to 4 bytes anyway.

通常空间现在不是一个问题,但如果你想真正优化存储出于某些原因(免责声明:不做预优化),你可以压缩lat(不超过91000个值+符号)+ long(不超过181 000个值+符号)到21位,这明显小于2xFLOAT(8字节== 64位)