现在大型网站已经实现了lbs基本上使用服务mongodb实现定位(gps不太清楚)。对于小型应用,一些大材料被小用,维护成本大大增加。在这里使用mysql来实现lbs的功能。
数据库设计层面,有两个方案
(1)字段主要包括 userId,lat,lng。分别代表用户ID、最近一次 Checkin 经度、纬度。
lat/lng 建立复合索引。
然后通过手机的定位得到自己的位置,比如记为 myLat,myLng。
代码如下,先做个计算,算出 1km 相应的经纬度范围:
double range = 180 / Math.PI * 1 / 6372.797;// 1 代表搜索 1km 内,单位km
double lngR = range / Math.cos(myLat* Math.PI / 180.0);
double maxLat = myLat range;
double minLat =myLat– range;
double maxLng = myLng lngR;
double minLng =myLng– lngR;
然后执行 SQL :
SELECT * FROM checkinTable WHERE ((lat BETWEEN ? AND ?) AND (lng BETWEEN ? AND ?))
这四个问号分别代入变量
minLat、maxLat、minLng、maxLng
然后你就可以查询结果了
但结果并不有序。
在客户端进行排序。
不建议在 SQL 层层执行,因为上述 SQL 可以用索引查询,一旦引入排序,就会影响效率。
(2)高级用法,但感觉有点大材小用。
就是使用 Spatial Index(空间索引)。MySQL 5.0 以上的系统都支持这种索引。
数据表可简化为 userId 和 userLocation。userLocation 是 Point 类型,同时建立 R-TREE 索引。
SQL 直接使用非标准 OpenGIS 函数 DISTANCE 就可以了。
这部分可以参考 MySQL Spatial Index Manual。若使用其它数据库,则应相似。
经过测试,发现这种方法确实实现了。对于小网站来说就够了。