请记住,我将在lat / long对上执行计算,什么数据类型最适合与MySQL数据库一起使用?
当前回答
博士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位)
其他回答
GeoLocationCoordinates返回一个双数据类型,以十进制表示位置的经纬度。你可以试着用double。
谷歌提供了一个从开始到结束的PHP/MySQL解决方案的例子“商店定位器”应用程序与谷歌地图。在本例中,它们将lat/lng值存储为“Float”,长度为“10,6”
http://code.google.com/apis/maps/articles/phpsqlsearch.html
根据您的应用程序,我建议使用FLOAT(9,6)
空间键将为您提供更多的功能,但在生产基准测试中,浮点数比空间键快得多。(在AVG中0,01 VS 0,001)
PostGIS中的空间函数比MySQL中的空间函数更具功能性(即不局限于BBOX操作)。看看:链接文本
我们将纬度/经度X 1,000,000作为数字存储在oracle数据库中,以避免使用双数舍入错误。
已知纬度/经度精确到小数点后第6位是10厘米,这就是我们所需要的。许多其他数据库也将lat/long存储到小数点后第6位。
推荐文章
- MySQL对重复键更新在一个查询中插入多行
- 有Java对象到对象映射的工具吗?
- mysql_connect():[2002]没有这样的文件或目录(试图通过unix:///tmp/mysql.sock连接)在
- 使用电子邮件地址为主键?
- MySQL:如何复制行,但改变几个字段?
- 不能删除或更新父行:外键约束失败
- Mysql错误1452:不能添加或更新子行:外键约束失败
- MySQL DISTINCT在GROUP_CONCAT()上
- 第一次设计数据库:我是否过度设计了?
- 我应该在SQL varchar(长度)中考虑电话的最长的全球电话号码是什么
- MySQL选择一个列DISTINCT,与其他列相对应
- 错误1022 -不能写;表中重复的键
- 如何修改列和更改默认值?
- 如何在MySQL 8.0中授予root用户所有权限
- mysqld_safe UNIX套接字文件目录“/var/run/mysqld”不存在