Mysql or Mongodb LBS快速实现方案
http://www.wubiao.info/470
前兩篇文章:
查找附近的xxx 球面距離以及Geohash方案探討 (http://www.wubiao.info/372)
微信、陌陌 架構方案分析 (http://www.wubiao.info/401)
探討了,LBS查找附近的XXX;其中包括了,Mysql自定義存儲函數方案,以及通過GeoHash、redis自建索引方案。
===============================================================
今天分享兩種,利用GeoHash封裝成內置數據庫函數的簡易方案;
A:Mysql 內置函數方案,適合于已有業務,新增加LBS功能,增加經緯度字段方可,避免數據遷移
B:Mongodb 內置函數方案,適合中小型應用,快速實現LBS功能,性能優于A(推薦)
===============================================================
方案A: (MySQL Spatial)
1、先簡歷一張表:(MySQL 5.0 以上 僅支持 MyISAM 引擎)
| 1 2 3 4 5 6 7 8 9 | CREATE TABLE address ( ????address CHAR(80) NOT NULL, ????address_loc POINT NOT NULL, ????PRIMARY KEY(address) ); |
空間索引:
| 1 | ALTER TABLE address ADD SPATIAL INDEX(address_loc); |
插入數據:(注:此處Point(緯度,經度) 標準寫法)
| 1 2 3 | INSERT INTO address VALUES('Foobar street 12', GeomFromText('POINT(30.620076 104.067221)')); INSERT INTO address VALUES('Foobar street 13', GeomFromText('POINT(31.720076 105.167221)')); |
查詢: 查找(30.620076,104.067221)附近 10 公里
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | SELECT? * ????FROM??? address ????WHERE?? MBRContains ????????????????????( ????????????????????LineString ????????????????????????????( ????????????????????????????Point ????????????????????????????????????( ????????????????????????????????????30.620076 + 10 / ( 111.1 / COS(RADIANS(104.067221))), ????????????????????????????????????104.067221 + 10 / 111.1 ????????????????????????????????????), ????????????????????????????Point ????????????????????????????????????( ????????????????????????????????????30.620076 - 10 / ( 111.1 / COS(RADIANS(104.067221))), ????????????????????????????????????104.067221 - 10 / 111.1 ????????????????????????????????????) ????????????????????????????), ????????????????????address_loc ????????????????????) |
方案B:
1、先建立一張簡單的表user,兩條數據如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | { ??"_id": ObjectId("518b1f1a83ba88ca60000001"), ??"account": "simplephp1@163.com", ??"gps": [ ????104.067221, ????30.620076 ??] } { ??"_id": ObjectId("518b1dae83ba88d660000000"), ??"account": "simplephp6@163.com", ??"gps": [ ????104.07958, ????30.653936 ??] } |
其中,gps為二維數組,分別為經度,緯度
(注:此處必須按照(經度,緯度)順序存儲。我們平時表示經緯度,都是(緯度,精度),此處這種方式有木有很親民)
2、使用之前,先建立二維索引
//建立索引 最大范圍在經度-180~180
| 1 | db.user.ensureIndex({"gps":"2d"},{"min":-180,"max":180}) |
//刪除索引
| 1 | db.user.dropIndex({"gps":"2d"}) |
3、Mongodb有兩中方式可以查找附近的XXX;其中方案2)會返回距離(推薦)
1)標準查詢,為地球經緯度查詢內置;參數一為查詢條件利用$near查找附近,參數二$maxDistance為經緯弧度(1° latitude = 111.12 kilometers)即 1/111.12,表示查找附近一公里。
| 1 | db.user.find({ gps :{ $near : [104.065847, 30.657554] , $maxDistance : 1/111.12} }) |
2)執行命名方式,模擬成一個圓球;參數一指定geoNear方式和表名;參數二坐標,參數三是否為球形,參數四弧度(弧度=弧長/半徑 一千米的弧度1000/6378000),參數五指定球形半徑(地球半徑)
| 1 | db.runCommand({geoNear:'user', near:[104.065847, 30.657554], spherical:true, maxDistance:1000/6378000, distanceMultiplier:6378000}); |
本條目發布于2013年05月28日。屬于DB、架構、算法分類,被貼了?geohash、LBS、Mongodb、Mysql?標簽。
總結
以上是生活随笔為你收集整理的Mysql or Mongodb LBS快速实现方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: xmpp整理笔记:xmppFramewo
- 下一篇: linux cmake编译源码,linu