数据库/ SQL:如何存储经度/纬度数据?


69

性能问题...

我有一个具有地理位置数据(经度和纬度)的房屋数据库。

我想做的就是找到使用InnoDB数据库引擎将位置数据存储在MySQL(v5.0.24a)中的最佳方法,这样我就可以执行很多查询,以返回介于两者之间的所有主记录。 x1和x2latitude以及y1和y2 longitude

现在,我的数据库架构是

---------------------
Homes   
---------------------
geolat - Float (10,6)
geolng - Float (10,6)
---------------------

我的查询是:

SELECT ... 
WHERE geolat BETWEEN x1 AND x2
AND geolng BETWEEN y1 AND y2
  • 我上面描述的是使用Float(10,6)在MySQL中存储经度和纬度数据并分离出经度/纬度的最佳方法吗?如果没有,那是什么?存在浮点数,小数甚至空间作为数据类型。
  • 从性能的角度来看,这是执行SQL的最佳方法吗?如果没有,那是什么?
  • 使用其他MySQL数据库引擎有意义吗?

更新:仍然没有答案

我在下面有3个不同的答案。一个人说要用Float。一个人说要用INT。一个人说要用Spatial

因此,我使用MySQL的“ EXPLAIN”语句来衡量SQL的执行速度。如果对经度和纬度数据类型使用INTFLOAT,则似乎在SQL执行(结果集获取)方面绝对没有区别。

看起来使用“ BETWEEN”语句比使用“ >”或“ <” SQL语句快得多。使用“ BETWEEN”比使用“ >”和“ <”语句快将近3倍。

话虽如此,我仍然不确定使用Spatial会对性能产生什么影响,因为我不清楚我的MySQL版本(v5.0.24)是否支持它,以及如何启用它(如果支持) 。

任何帮助将不胜感激


1
如果度是您应用程序的自然格式,请使用FLOAT,因此您不必进行转换。储存为INT的微度为您提供更高的精度。您不能在表演上击败这两个。仅在需要空间索引时才考虑空间扩展。
ZZ编码器

@ZZ Coder,我不介意进行转换-我只是在寻找根据上述用例得出的哪种数据类型将返回最快的SQL结果集。另外,我编写SQL的方式效率最高吗?

只要您有lat-lon索引,您的查询就应该很快。我们选择INT是因为我们的DBA告诉我们float的索引很慢,但是我从来没有尝试过,所以不知道它有多慢。您还可以通过在此查询返回的视图上使用@geodist()来相当快地获得循环选择。
ZZ编码器

Answers:


27

float(10,6)很好。

任何其他复杂的存储方案都需要进出更多的转换,并且浮点数学运算速度很快。


@richardtallent,您是在说1)我如何存储数据,2)我选择的数据类型,3)我的SQL语句和4)我的InnoDB数据库引擎...所有这些都已经选择/设计了成为绝对最有效的使用方式(最佳性能)?

@richardtallent,意思是-我无法进行任何更改以使其性能更好

5
+1有一个读coordinate.codeplex.com其中海梅·奥利瓦雷斯解释了为什么花车的正确类型的坐标...
手榴弹

10

我知道您在询问MySQL,但如果空间数据对您的业务很重要,则可能需要重新考虑。PostgreSQL + PostGIS也是免费软件,它们在有效管理空间和地理数据方面享有盛誉。许多人仅因为PostGIS而使用PostgreSQL。

不过,我对MySQL空间系统了解不多,因此对于您的用例来说,它可能工作得很好。


我可能需要调查一下。关于在框坐标(经度/纬度)之间获取所有记录的性能的任何信息吗?

从5.6版开始,MySQL现在是GIS功能的重要竞争者。
哥顿


5

使用“空间”以外的任何其他数据类型的问题是,您的“矩形选择”可以(通常取决于您的DBMS的亮度-MySQL通常不是最亮的)只能在一个中进行优化单一维度。

系统可以选择经度索引或纬度索引,并使用它们来减少要检查的行集。但是,这样做之后,可以选择:(a)获取所有找到的行并对其进行扫描,然后测试“其他维度”,或者(b)在“其他维度”上执行类似的过程,然后再进行匹配这两个结果集,以查看哪些行同时出现在这两个行中。后一个选项可能无法在您的特定DBMS引擎中实现。

空间索引可以“自动”完成后者的操作,因此我可以肯定地说,空间索引在任何情况下都能提供最佳性能,但也有可能它并没有明显优于其他解决方案,并且只是不值得打扰。这取决于各种各样的事情,例如实际数据的数量和分布等。

的确,浮点(树)索引必然比整数索引慢,因为在浮点上执行'>'通常比在整数上花费更长的时间。但是,如果这种效果实际上很明显,我会感到惊讶。


我使用“ IN BETWEEN” SQL语句测试了Float vs INT,并使用EXPLAIN和BENCHMARK命令测量了时间,结果集查询的差异在速度上的差异小于1%。但是,使用“>”或“ <”运算符,而不是“介于两者之间”,会导致查询执行时间延长近3倍。

因此,只要您使用“ IN BETWEEN” SQL语句,使用FLOAT与INT之间似乎没有区别。

我无法测试Spatial,因为我尚不清楚我的版本(v5.0.24)是否支持现成的Spatial,还是我必须以某种方式安装扩展/插件

4

我会将其存储为int以1 / 1,000,000th度表示的整数(,4个字节)。那会给你几英寸的分辨率。

我认为MySQL中没有任何固有的空间数据类型。


1
@ZZ编码器,对空间数据类型信息- > dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html

此外,您声明使用INT。如何将像93.2343213这样的数据存储为INT?

@哈维尔,负多头/纬度怎么样?假设所有long / lat均为正值-仅对东北半球有效-> en.wikipedia.org/wiki/ISO_6709

@Timtom:由于这是一个性能问题,除非您需要空间索引,否则您可能不希望使用GIS /空间扩展。以WKB表示的点大约需要20个字节。也不是所有引擎都支持。
ZZ编码器

@Timtom:INT已签名,因此您可以存储负值。只需将您的学位值乘以1,000,000。
ZZ Coder

4

浮点(10,6)

纬度或经度5555.123456在哪里?

您不是说Float(9,6)吗?


MySQL在存储FLOAT和时会忽略分辨率规范DOUBLE。它仅使用32位或64位浮点。在现代机器上,很可能会遵循IEEE 754 binary32和binary64标准。
O. Jones

@OllieJones您能否进一步解释一下。我也有同样的疑问,为什么不浮动(9,6)?
Nikunj Madhogaria

2

我有完全相同的架构(float(10,6))和查询(在矩形内选择),我发现将数据库引擎从innoDB切换到myisam可使表中“在矩形中查找点”的速度提高了一倍有780,000条记录。

另外,我将所有的lng / lat值都转换为笛卡尔整数(x,y),并在x,y上创建了一个两列索引,对于相同的查找,我的速度从〜27 ms变为1.3 ms。


0

这实际上取决于您如何使用数据。但是,在事实的过度简化中,十进制的速度更快,但近似值的准确性较低。更多信息在这里:

http://msdn.microsoft.com/zh-CN/library/aa223970(SQL.80).aspx

另外,ISO 6709中指定了GPS坐标标准:

http://en.wikipedia.org/wiki/ISO_6709


@Armitage,假设我有一列用于纬度,而coloum则用于经度。而且我存储数据,例如,93.12342342

@Armitage,也许我应该问-为什么要在MySQL中存储长/纬度数据的最好方法是什么?假设我想做很多查询,在这些查询中我返回的是x1和x2纬度以及y1和y2经度之间的所有记录。

听起来性能差异可以忽略不计。从我阅读的内容来看,Spacial的性能会更好,并且可能会节省您编写项目的时间,但是我从未使用过它。
AyexeM
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.