例如,假设我有一张桌子:
Business(BusinessID, Lattitude, Longitude)
当然,所有内容都已编入索引。还有100万条记录
假设我想找到最接近 106,5 的商家,例如,我该怎么做?
如果我做
SELECT *
FROM Business
WHERE (Some formula to compute distance here) < 2000
例如,或者如果我这样做
SELECT *
FROM Business
TOP 20
理论上,计算机必须计算所有商务的距离,而实际上只有那些在一定范围内的纬度和经度才需要计算。
那么我怎样才能在 PhP 或 SQL 中做我想做的事情呢?
到目前为止,我很感激答案。我正在使用 mysql,他们没有比明显的解决方案更有效的方法。MySQL 空间也没有计算距离功能。
如果我正确理解了这个问题(我不确定我是否理解),您是否担心
"(Some formula to compute distance here)"
每次执行查询时都会计算表中的每一行?这可以通过使用索引在一定程度上缓解,
latitude
因此longitude
我们只需要计算包含我们实际想要的圆的“盒子”点的距离:选择 96、116 等以匹配值“2000”的单位和地球上您计算距离的点。
这使用索引的精确程度将取决于您的 RDBMS 及其规划者所做的选择。
一般而言,这是优化一种最近邻搜索的原始方式。如果您的 RDBMS 支持GiST 索引,例如postgres ,那么您应该考虑使用它们。
(披露:我是 Microsoft SQL Server 的人,所以我的答案受此影响。)
要真正有效地做到这一点,您需要两件事:缓存和本机空间数据支持。 空间数据支持使您可以将地理和几何数据直接存储在数据库中,而无需即时进行密集/昂贵的计算,并允许您构建索引以非常快速地找到离您当前位置最近的点(或最有效的路线或其他任何东西)。
如果您想扩展,缓存很重要。最快的查询是您从未做过的查询。每当用户询问离他最近的东西时,您会将他的位置和结果集存储在 Redis 或 memcached 等缓存中几个小时。营业地点不会在 4 小时内发生变化 - 好吧,如果有人编辑了一家公司,它们可能会发生变化,但您不一定需要在所有结果集中立即更新。
Yelp 可能使用 GIS
PostgreSQL 具有使用PostGIS的 GIS 参考实现。Yelp 可能正在使用在各方面都较差的 MySQL。对于像 Yelp 这样的东西,他们几乎肯定会保留坐标,
这些坐标几乎肯定在 WGS84 中,并存储为地理类型。在 PostgreSQL 和 PostGIS 中,它看起来像这样,
他们会填满那张桌子。然后他们从您的手机中获取 WGS84 坐标并生成查询,就像使用 SQL Alchemy(以 Yelp 为例)一样,
有关更多信息,请参阅我们的空间,并查看地理信息系统@StackExchange