请记住,我将在lat / long对上执行计算,什么数据类型最适合与MySQL数据库一起使用?
当前回答
不需要走太远,根据谷歌地图,最好是FLOAT(10,6)的纬度和液化天然气。
其他回答
当我从ARINC424构建导航数据库时,我做了相当多的测试,并回顾了代码,我使用了DECIMAL(18,12)(实际上是NUMERIC(18,12),因为它是firebird)。
浮点数和双精度数没有那么精确,可能会导致舍入错误,这可能是一件非常糟糕的事情。我不记得我是否发现了任何有问题的真实数据——但我相当肯定无法准确地存储在浮点数或双精度数中可能会导致问题
关键是,当使用角度或弧度时,我们知道值的范围——小数部分需要最多的数字。
MySQL空间扩展是一个很好的选择,因为它们遵循OpenGIS几何模型。我没有使用它们,因为我需要保持数据库的可移植性。
根据您的应用程序,我建议使用FLOAT(9,6)
空间键将为您提供更多的功能,但在生产基准测试中,浮点数比空间键快得多。(在AVG中0,01 VS 0,001)
不需要走太远,根据谷歌地图,最好是FLOAT(10,6)的纬度和液化天然气。
这取决于你需要的精度。
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不支持索引(5.6除外,当表类型为MyISAM时)。
注意:
使用POINT类时,用于存储坐标的参数的顺序必须是POINT(纬度,经度)。 创建空间索引有一种特殊的语法。 使用SDT的最大好处是您可以访问空间分析函数,例如计算两点之间的距离(ST_Distance)和确定一个点是否包含在另一个区域(ST_Contains)。
博士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位)
推荐文章
- 警告用户/local/mysql/data目录不属于mysql用户
- 添加一个复合主键
- 无法添加或更新子行:外键约束失败
- 如何从本地机器mysqldump远程数据库
- 如何正确地创建复合主键- MYSQL
- 仅在Datetime列上按日期分组
- 在MySQL数据库中存储货币值的最佳数据类型
- 如何自定义'显示进程列表'在mysql?
- 多语言数据库设计的最佳实践是什么?
- MySQL删除一些外键
- 用MySQL LEFT JOIN删除行
- MySQL - length() vs char_length()
- 使用PDO进行行计数
- 在Mac上安装MySQL后,使用ALTER USER语句重置MySQL root密码
- my.cnf文件在macOS上的位置