参考文档:
http://blog.csdn.net/wangxiafghj/article/details/9014363geohash 算法原理及实现方式 http://blog.charlee.li/geohash-intro/ geohash:用字符串实现附近地点搜索 http://blog.sina.com.cn/s/blog_7c05385f0101eofb.html 查找附近点--Geohash方案讨论 http://www.wubiao.info/372 查找附近的xxx 球面距离以及Geohash方案探讨 http://en.wikipedia.org/wiki/Haversine_formula Haversine formula球面距离公式 http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe 球面距离公式代码实现 http://developer.baidu.com/map/jsdemo.htm#a6_1 球面距离公式验证 http://www.wubiao.info/470 Mysql or Mongodb LBS快速实现方案 geohash有以下几个特点: 首先,geohash用一个字符串表示经度和纬度两个坐标。某些情况下无法在两列上同时应用索引 (例如MySQL 4之前的版本,Google App Engine的数据层等),利用geohash,只需在一列上应用索引即可。 其次,geohash表示的并不是一个点,而是一个矩形区域。比如编码wx4g0ec19,它表示的是一个矩形区域。 使用者可以发布地址编码,既能表明自己位于北海公园附近,又不至于暴露自己的精确坐标,有助于隐私保护。 第三,编码的前缀可以表示更大的区域。例如wx4g0ec1,它的前缀wx4g0e表示包含编码wx4g0ec1在内的更大范围。 这个特性可以用于附近地点搜索。首先根据用户当前坐标计算geohash(例如wx4g0ec1)然后取其前缀进行查询 (SELECT * FROM place WHERE geohash LIKE 'wx4g0e%'),即可查询附近的所有地点。
一直在琢磨LBS,期待可以发现更好的方案。现在纠结了。
简单列举一下已经了解到的方案: 1.sphinx geo索引 2.mongodb geo索引 3.mysql sql查询 4.mysql+geohash 5.redis+geohash
然后列举一下需求: 1.实时性要高,有频繁的更新和读取 2.可按距离排序支持分页 3.支持多条件筛选(一个经纬度数据还包含其他属性,比如社交系统的性别、年龄)
方案简单介绍: 1.sphinx geo索引 支持按照距离排序,并支持分页。但是尝试mva+geo失败,还在找原因。 无法满足高实时性需求。(可能是不了解实时增量索引配置有误) 资源占用小,速度快
2.mongodb geo索引 支持按照距离排序,并支持分页。支持多条件筛选。 可满足实时性需求。 资源占用大,数据量达到百万级请流量在10w左右查询速度明显下降。
3.mysql+geohash/ mysql sql查询 不支持按照距离排序(代价太大)。支持分页。支持多条件筛选。 可满足实时性需求。 资源占用中等,查询速度不及mongodb。 且geohash按照区块将球面转化平面并切割。暂时没有找到跨区块查询方法(不太了解)。
4.redis+geohash geohash缺点不再赘述 不支持距离排序。支持分页查询。不支持多条件筛选。 可满足实时性需求。 资源占用最小。查询速度很快。
------update 补充一下测试机配置: 1TB SATA硬盘。8GB RAM。I3 2350 双核四线程