gpt4 book ai didi

php - 使用空间分析功能和数据类型在 MySQL 中按距离排序

转载 作者:可可西里 更新时间:2023-11-01 06:37:06 25 4
gpt4 key购买 nike

我正在使用 Laravel 5.5 构建一个 php 网络应用程序,我需要显示一个地点列表(例如商店),这些地点按它们与用户指定位置的距离排序。这些地点将存储在 MySQL 数据库中,并应作为 Eloquent ORM 模型实例进行检索。

做一些研究我发现了很多关于这个主题的帖子和问题(提出了不同的解决方案),但是,由于在数据库和地理定位/地理空间分析方面的经验很少,他们大多让我感到困惑,我想知道什么方法遵循以及在这种情况下的最佳做法是什么。

我读到的大多数答案都建议使用 haversine formulaspherical law of cosines在 SQL 查询中,它看起来像(示例取自 this answer ):

$sf = 3.14159 / 180; // scaling factor
$sql = "SELECT * FROM table
WHERE lon BETWEEN '$minLon' AND '$maxLon'
AND lat BETWEEN '$minLat' AND '$maxLat'
ORDER BY ACOS(SIN(lat*$sf)*SIN($lat*$sf) + COS(lat*$sf)*COS($lat*$sf)*COS((lon-$lon)*$sf))";

This post指出这样一个事实,即在短距离内,假设地球是平的并计算一个简单的欧氏距离是一个很好的近似值,并且比使用半正弦公式更快。<​​br/>由于我一次只需要对一个城市内的地点进行排序,这似乎是一个很好的解决方案。

但是,这些帖子和 SO 答案中的大多数都是几年前的,我想知道现在(MySQL 5.7)是否有更好的解决方案。

例如,这些帖子都没有使用任何 MySQL 的“空间分析功能”,例如 ST_Distance_SphereST_Distance这似乎正是为了这个目的。
是否有任何理由(例如性能、精度)使用这些函数而不是在查询中编写公式? (我不知道这些函数内部使用的是哪种算法)

我也不知道应该如何存储每个地方的坐标。我见过的大多数示例都假设坐标以 double 或 FLOAT(10,6) 形式存储在单独的 latlon 列中> (如 this example by google ),而且 MySQL POINT 数据类型似乎也适合存储地理坐标。
这两种方法的优缺点是什么?

如何使用索引来加速此类查询?例如,我读过 “spatial indexes” ,但我认为它们只能用于限制结果,例如 MBRContains(),而不是按距离实际排序结果。

那么,我应该如何存储地点的坐标以及如何查询它们以按距离排序?

最佳答案

除了 ST_Distance_Sphere,5.7 没有带来任何额外的东西。 (SPATIAL 已经实现。)

对于“数千”点,您拥有的代码可能是最好的。包括

INDEX(lat, lng),
INDEX(lng, lat)

除非您延伸数千英里 (km),否则我不会担心地球的曲率。即使这样,代码和该功能也应该足够好。

不要使用FLOAT(m,n),只使用FLOAT。下面的链接提供了 FLOAT 和其他表示形式可用的精度。

如果你有太多的点,你不能完全缓存表和它的索引(数百万个点),你可以使用 this ,它使用了一些技巧来避免像上述解决方案那样的冗长扫描。由于 PARTITION 限制,lat/lng 表示为按比例缩放的整数。 (但这很容易在输入/输出中进行转换。)地球的曲率、两极和日期变更线都已处理。

关于php - 使用空间分析功能和数据类型在 MySQL 中按距离排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48490309/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com