铭记我会执行的计算,在纬度/经度对,什么样的数据类型是最适合用一个数据库?

有帮助吗?

解决方案

在GIS中使用MySQL的空间扩展

其他提示

Google提供了一个开始完成PHP / MySQL解决方案的示例“商店定位器”使用Google地图申请。在这个例子中,它们将lat / lng值存储为“Float”。长度为“10,6”

http://code.google.com/apis/maps/articles/ phpsqlsearch.html

基本上,这取决于您所在位置所需的精度。使用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的Spatial Extensions是最佳选择,因为您可以使用空间运算符和索引的完整列表。空间索引将允许您非常快速地执行基于距离的计算。请记住,从6.0开始,Spatial Extension仍然不完整。我没有放下MySQL Spatial,只是在你走得太远之前让你知道陷阱。

如果您严格处理积分并且只处理DISTANCE功能,那么这很好。如果您需要使用多边形,线条或缓冲点进行任何计算,空间运算符不会提供精确的结果,除非您使用“关联”和“关联”。运营商。请参阅 21.5.6 。包含,内部或相交等关系使用MBR,而不是精确的几何形状(即椭圆被视为矩形)。

此外,MySQL Spatial中的距离与第一个几何体的距离相同。这意味着如果您使用十进制度数,则您的距离测量值为十进制度数。这将使你很难得到准确的结果,因为你从赤道得到了更好的结果。

当我为ARINC424构建的导航数据库执行此操作时,我进行了大量测试并回顾了代码,我使用了DECIMAL(18,12)(实际上是NUMERIC(18,12),因为它是firebird )。

浮动和双打并不精确,可能会导致舍入错误,这可能是一件非常糟糕的事情。我不记得我是否发现任何有问题的真实数据 - 但我相当确定无法准确存储在浮点数或双数据中可能会导致问题

关键是当使用度数或弧度时,我们知道值的范围 - 而小数部分需要最多的数字。

MySQL Spatial Extensions 是一个不错的选择因为他们遵循 OpenGIS几何模型。我没有使用它们,因为我需要保持数据库的可移植性。

取决于精密,你需要的。

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).

作为的 MySQL5.7, 考虑使用 空间数据的类型 (SDT),具体而言 POINT 用于储存一个单一的协调。前5.7,特殊和差别待遇不支持索引(与例外的5.6时表型是些).

注:

  • 当使用 POINT 类参数的顺序,用于储存的坐标必须 POINT(latitude, longitude).
  • 有一个特殊的语法 创造一个空间索引.
  • 最大的利益使用特殊和差别待遇是的,你有访问 空间分析功能, 如计算两点之间的距离(ST_Distance)和确定是否有一个点被包含在另一个领域(ST_Contains).

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

对经度(180到-180度)使用 DECIMAL(8,6)表示纬度(90到-90度)和 DECIMAL(9,6)。对于大多数应用程序,小数点后6位。两者都应该“签名”。允许负值。

根据谷歌地图的说法,没有必要走得太远,对于lat和lng,最好的是FLOAT(10,6)。

我们在oracle数据库中将纬度/经度X 1,000,000存储为NUMBERS,以避免双打错误。

鉴于小数点后第6位的纬度/经度是10厘米精度,这就是我们所需要的。许多其他数据库也将lat / long存储到小数点后6位。

在一个完全不同和更简单的观点:

  • 如果你依靠在谷歌上表示了你的地图,标记、面不管,那我们的计算是通过谷歌!
  • 你节省的资源在你的服务器你只是储存的纬度和经度一起作为一个单一的string(VARCHAR),例如:"-0000.0000001,-0000.000000000000001"(35长度和如果一个数字已经超过7小数位数,然后它得到圆);
  • 如果是谷歌的回报超过7小数位数的每个数字,你可以得到数据保存在你的串无论如何,刚果你想检测一些 出逃或微生物的未来;
  • 你可以使用他们的 距离矩阵 或者他们的 几何图书馆 用于计算距离,或 检测点在某些领域 与的呼吁如此简单: google.maps.geometry.poly.containsLocation(latLng, bermudaTrianglePolygon))
  • 有很多的"服务器的端"Api可以使用(在 蟒蛇, 红宝石在轨道上, PHP, , Laravel, , Zend框架, 等)。 使用谷歌地图。

这样你不需要担心,索引编号和所有其他相关问题的数据类型可能会搞砸了你的坐标。

取决于您的申请,我建议使用FLOAT(9,6)

空间键将为您提供更多功能,但在生产基准测试中,浮点数比空间键快得多。 (AVG中0,01 VS 0,001)

MySQL对所有浮点数使用double ... 所以使用double类型。在大多数情况下使用float会导致不可预测的舍入值

虽然它不是最佳的,对于所有操作,如果你正在做地图瓦或使用大型号标记(dots)只有一个投射(例如Mercator,如谷歌地图和其他许多滴水成冰的地图框架预期),我们发现什么我呼叫"庞大的坐标系统"是真的,真的派上用场。基本上,你存储x和y素坐标在某些方-放大-我使用的缩放水平23.这有几个优点:

  • 你做的昂贵的lat/液化天然气mercator素变换一次而不是每次处理点
  • 得到的坐标从一个记录给予一个放水平需要一个正确的转变。
  • 越来越像素的协调,从记录需要一个权利移和一个位。
  • 变化是如此的轻便,它是实用做他们在SQL,这意味着你可以做一个独特的返回只有一个记录每一像素的位置,这将削减数记录返回的后端,这意味着较少的处理在前结束。

我谈到了所有这一切都在最近一篇博客: http://blog.webfoot.com/2013/03/12/optimizing-map-tile-generation/

我非常惊讶的一些答案/意见。

为什么地球上会有人愿意voluntarely"预先减少"精度,然后在执行计算上更糟糕的数字?听起来最终愚蠢的。

如果来源有64位精度,它肯定将是愚蠢voluntarely解决规模如。6小数,并限制的精确度最高的9个重大digts(其中发生的,与通常提出的十进制9.6格式)。

当然,一个存储数据的精确度来源的材料。的唯一原因来降低精确度将是有限的储存空间。

  • 存储来源的数字与原来的精确度
  • 商店的数字计算来源的精算情况(例如。如果应用程序的代码使用加倍,结果存储为双)

小数9.6-格式引起捕捉到格现象.这应该是最后的步骤,如果它是在所有情况发生。

我不会邀请累积的错误。来我的窝。

PostGIS中的空间函数比MySQL空间函数中的空间函数功能更强大(即不受BBOX操作限制)。看看:链接文字

TL博士

使用的浮动(为8,5)如果你不工作,在美国国家航空航天局/军和不进飞机的导航系统。


来回答你的问题充分,你会需要考虑的几件事情:

格式

  • 度分秒:40°26'46"N79°58'56"W
  • 度十进制分钟:40°26.767'N79°58.933'W
  • 十进制的度1:40.446°N79.982°W
  • 十进制的度2: -32.60875, 21.27812
  • 一些其他家庭成的格式?没人禁止你做你自己的家庭为中心的坐标系统和存储它作为走向和距离你的家。这可能是有意义的一些具体问题,你的工作。

所以第一部分答案将是-你可以储存的坐标 格式应用程序使用 为了避免不断转换回和让更简单SQL查询。

最可能使用的谷歌地图或OSM以显示您的数据,并允许你搜索使用的"十进制的度2"格式。因此,它会更容易储存的坐标在相同的格式。

精密

然后,你会喜欢的定义精确,你需要的。当然你可以储存的坐标,如"-32.608697550570334,21.278081997935146",但你曾经关心毫米时的导航这一点?如果你不工作,在美国航天局和不干卫星或火箭或飞机轨迹,你应该没有几米的精度。

通常使用的格式是5位数后点给你50厘米的精度。

:有1厘米间距离X,21.2780818 和X,21.2780819.所以7位数后点给你1/2厘米的精度和5位数点后会给你的1/2米的精确度(因为最小的距离之间的不同点是1m,所以四舍五入错误不能超过一半)。对于大多数公民的目的应该是足够的。

度十进制分的格式(40°26.767'N79°58.933'W)为您提供完全相同的精确度为5位数后点

空间效率的储存

如果你已经选择的小数格式,然后你的坐标是对(-32.60875,21.27812).很明显,2x(1位为标志,2位数度和5位数的指数)将是不够的。

所以我在这里想到的支持 Alix阿克塞尔 从评论说,谷歌的建议,以存放在浮(的10,6)真是额外的,因为你不需要4位数的主要部分(因为签署是分离和纬度是有限的90度和经度是有限的180).你可以很容易地使用的浮动(8,5月)的1/2m精密或浮动(9,6的交付)50/2厘米的精度。或者你甚至可以存储纬度和长期分离的类型,因为FLOAT(自7,5)是足够的纬度。见MySQL浮动的类型 参考.任何的他们会像正常浮动和平等的4个字节,反正。

从空间不是问题的现在,但是如果你想要真的很优化存储由于某些原因(免责声明:不要做预先优化),可能压缩纬度(不超过91 000值+签署)+长期(不超过181 000值+签署)的21位是 明显少 比2xFLOAT(8bytes==64位)

  1. 纬度范围从-90到+90(度),因此DECIMAL(10,8)可以用于

  2. 经度范围从-180到+180(度),所以你需要DECIMAL(11,8)。

  3. 注意:第一个数字是存储的总位数,第二个数字是小数点后面的数字。

    简而言之: lat DECIMAL(10,8)NOT NULL,lng DECIMAL(11,8)NOT NULL

Lat Long计算需要精度,因此请使用某种类型的十进制类型,并使精度至少比存储的数字高2,以便执行数学计算。我不知道我的sql数据类型,但在SQL服务器中,人们经常使用float或real而不是decimal,并且遇到麻烦,因为这些是估计的数字而不是真正的数字。因此,只需确保您使用的数据类型是真正的十进制类型而不是浮动十进制类型,您应该没问题。

FLOAT 应该为您提供所需的所有精度,并且比将每个坐标存储为字符串等更好地用于比较函数。

如果您的MySQL版本早于5.0.3,您可能需要注意某些浮点比较错误然而。

  

在MySQL 5.0.3之前,DECIMAL列以精确的精度存储值,因为它们表示为字符串,但DECIMAL值的计算是使用浮点运算完成的。从5.0.3开始,MySQL执行DECIMAL操作,精度为64位十进制数,这可以解决DECIMAL列中最常见的不准确问题

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top