我正在开发一个小应用程序,它将iOS设备指定的 Placemarks 存储到MySQL后端。当设备保存新的地标时,会将其插入数据库,并将新生成的ID发送回客户端。如果其他设备尝试保存相同的地标,则服务器需要确定它已存在于数据库中,而不是INSERT并生成新ID,而是需要将其发送回客户端该地标的现有ID。
2 地标如果相同则相同:
因此,服务器会尝试通过发出
来识别提交的地标是否已存在SELECT id FROM Placemark WHERE name = x,latitude = y,longitude = x
latitude
longitude
和CLLocationDegrees
为度数,<CoreLocation>
为latitude
类型
longitude
和DOUBLE
被定义为latidude
问题:
存储坐标时精度会丢失,例如:
50.09529561485427
50.0952956148543
longitude
存储为-122.9893130423316
-122.989313042332
TEXT
VARCHAR
存储为SELECT placemarks coordinates BETWEEN x AND y
问题:
我可以在MySQL中使用不同的数据类型,以便保存每个坐标吗?
备注:
任何帮助表示赞赏
答案 0 :(得分:3)
实际上,进一步的测试揭示了以下奇怪的结果:当数据库驱动程序将数据绑定到查询语句时精度会丢失,而之前数据实际插入数据库中。
这有以下有趣的结果:即使我将键绑定到后续的搜索查询,精度似乎也以相同的方式丢失,因此几乎“偶然”返回正确的结果。也就是说,键(坐标)存储不正确,然后后续选择也错误地转换查询键,但是以匹配的方式,因此找到记录。鉴于由于精度损失导致的转换总是在同一平台(服务器)上执行,因此可能会安全地离开?或者可能不是,也许未来的迁移练习(即,由于缩放)将使舍入误差明显。
Yawar的指针引导我阅读MySQL的手册,该手册解释了浮点数可以在不损失精度的情况下存储为DECIMAL:
“精确值数字文字具有整数部分或小数部分,或两者兼而有之。它们可能已签名” http://dev.mysql.com/doc/refman/5.0/en/precision-math-decimal-changes.html
鉴于现有解决方案似乎有效,问题就变成了,保持数据库数据类型DOUBLE
或切换到DECIMAL
更好吗?
<强>存储强>
Latitude
的范围为-90 to +90
,iOS似乎使用14 decimals
的精度
Longitude
的范围为-180 to +180
,在iOS上保留13 decimals
的精度
这意味着我们需要:
Latitude
:DECIMAL(16,14)
,占用较少的8个字节的存储空间(每个包9个字节为4个字节)
Longitude
:DECIMAL(16,13)
,还需要少于8个字节的存储空间
相反,DOUBLE
类型的列需要8个字节的存储空间。
速度(算术):
浮点运算几乎总是更快,因为它本身由硬件支持
速度(搜索):
我认为DECIMAL
索引与DOUBLE
索引具有非常相似的运行时间。
<强>结论:强>
切换到DECIMAL
可以消除精度错误并降低存储要求,但算术性能损失在此用例中可以忽略不计。
答案 1 :(得分:0)
不是将纬度和经度存储为double,乘以1000000,转换为整数,然后存储它。当然,如果您需要在应用程序中阅读它们,则除以1000000.0。
这将为地标提供足够的精度(0.000001º),并将消除您所拥有的浮点转换和精度问题,并占用更少的空间。我在我自己的数据中使用它(它是二进制文件,而不是SQL)并称之为MicroDegrees。