日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

【学习笔记】Redis的geohash数据结构介绍

發布時間:2024/9/30 数据库 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【学习笔记】Redis的geohash数据结构介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

geohash介紹

?Redis 3.2開始,Redis基于geohash和有序集合提供了地理位置相關功能。Redis Geo模塊包含了以下6個命令:
?GEOADD: 將給定的位置對象(緯度、經度、名字)添加到指定的key;
?GEOPOS: 從key??返回所有給定位置對象的位置(經度和緯度);
?GEODIST: 返回兩個給定位置之間的距離;
?GEOHASH: 返回?個或多個位置對象的Geohash表?;
?GEORADIUS: 以給定的經緯度為中?,返回?標集合中與中?的距離不超過給定最?距離的所有位置對象;
?GEORADIUSBYMEMBER: 以給定的位置對象為中?,返回與其距離不超過給定最?距離的所有位置對象。
其中,組合使?GEOADD和GEORADIUS可實現“附近的?”中“增”和“查”的基本功能。要實現微信中“附近的?”功能,可直接使?GEORADIUSBYMEMBER命令。其中“給定的位置對象”即為??本?,搜索的對象為其他??。不過本質
上,GEORADIUSBYMEMBER = GEOPOS + GEORADIUS,即先查找??位置再通過該位置搜索附近滿?位置相互距離條件的其他??對象。
以下會從源碼?度??對GEOADD和GEORADIUS命令進?分析,剖析其算法原理

Redis geo操作中只包含了“增”和“查”的操作,并沒有專?的“刪除”命令。主要是因為Redis內部使?有序集合(zset)保存位置對象,可?zrem進?刪除。
在Redis源碼geo.c的?件注釋中,只說明了該?件為GEOADD、GEORADIUSGEORADIUSBYMEMBER的實現?件(其實在也實現了另三個命令)。從側?看出其他三個命令為輔助命令。

GEOADD

使??式
GEOADD key longitude latitude member [longitude latitude member …]
將給定的位置對象(緯度、經度、名字)添加到指定的key。
其中,key為集合名稱,member為該經緯度所對應的對象。在實際運?中,當所需存儲的對象數量過多時,可通過設置多
key(如?個省?個key)的?式對對象集合變相做sharding,避免單集合數量過多。
成功插?后的返回值:
(integer) N
其中N為成功插?的個數。

通過源碼分析可以看出Redis內部使?有序集合(zset)保存位置對象,有序集合中每個元素都是?個帶位置的對象,元素的score值為其經緯度對應的52位的geohash值。
double類型精度為52位;
geohash是以base32的?式編碼,52bits最?可存儲10位geohash值,對應地理區域??為0.60.6?的格?。換句話說經Redis geo轉換過的位置理論上會有約0.31.414=0.424?的誤差。(?)

簡單總結下GEOADD命令都?了啥:
1、參數提取和校驗;
2、將?參經緯度轉換為52位的geohash值(score);
3、調?ZADD命令將member及其對應的score存?集合key中。

GEORADIUS

使??式

GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count] [STORE key] [STORedisT key]

以給定的經緯度為中?,返回?標集合中與中?的距離不超過給定最?距離的所有位置對象。
范圍單位:m | km | ft | mi --> ? | 千? | 英尺 | 英?
額外外參數:

  • WITHDIST:在返回位置對象的同時,將位置對象與中?之間的距離也?并返回。距離的單位和??給定的范圍單位保持?致。
  • WITHCOORD:將位置對象的經度和維度也?并返回。
  • WITHHASH:以 52 位有符號整數的形式,返回位置對象經過原始 geohash 編碼的有序集合分值。這個選項主要?于底層應?
    或者調試,實際中的作?并不?。
  • ASC|DESC:從近到遠返回位置對象元素 | 從遠到近返回位置對象元素。
  • COUNT count:選取前N個匹配位置對象元素。(不設置則返回所有元素) - STORE key:將返回結果的地理位置信息保存到
    指定key。
  • STORedisT key:將返回結果離中?點的距離保存到指定key。

由于 STORE 和 STORedisT 兩個選項的存在,GEORADIUS 和 GEORADIUSBYMEMBER 命令在技術上會被標記為寫?命令,從?只會查詢(寫?)主實例,QPS過?時容易造成主實例讀寫壓?過?。為解決這個問題,在 Redis 3.2.10 和 Redis 4.0.0 中,分別新增了 GEORADIUS_RO 和 GEORADIUSBYMEMBER_RO兩個只讀命令。
不過,在實際開發中筆者發現 在java package Redis.clients.jedis.params.geo 的 GeoRadiusParam 參數類中并不包含STORE 和 STORedisT 兩個參數選項,在調?georadius時是否真的只查詢了主實例,還是進?了只讀封裝。
成功查詢后的返回值:
不帶WITH限定,返回?個member list,如:
[“member1”,“member2”,“member3”]
帶WITH限定,member list中每個member也是?個嵌套list,如:
[
[“member1”, distance1, [longitude1, latitude1]]
[“member2”, distance2, [longitude2, latitude2]]
]

?結
拋開眾多可選參數不談,簡單總結下GEORADIUS命令是怎么利?geohash獲取?標位置對象的:
1、參數提取和校驗;
2、利?中?點和輸?半徑計算待查區域范圍。這個范圍參數包括滿?條件的最?的geohash?格等級(精度) 以及 對應的能夠覆蓋?標區域的九宮格位置;(后續會有詳細說明)
3、對九宮格進?遍歷,根據每個geohash?格的范圍框選出位置對象。進?步找出與中?點距離?于輸?半徑的對象,進?返回。
直接描述不太好理解,我們通過如下兩張圖在對算法進?簡單的演?:

令左圖的中?為搜索中?,綠?圓形區域為?標區域,所有點為待搜索的位置對象,紅?點則為滿?條件的位置對象。
在實際搜索時,?先會根據搜索半徑計算geohash?格等級(即右圖中?格??等級),并確定九宮格位置(即紅?九宮格位置信息);再依次查找計算九宮格中的點(藍點和紅點)與中?點的距離,最終篩選出距離范圍內的點(紅點)。

如何通過geohash?格的范圍框選出元素對象?效率如何?
?先在每個geohash?格中的geohash值都是連續的,有固定范圍。所以只要找出有序集合中,處在該范圍的位置對象即可。以下是有序集合的跳表數據結構:

其擁有類似?叉查找樹的查詢效率,操作平均時間復雜性為O(log(N))。
且最底層的所有元素都以鏈表的形式按序排列。
所以在查詢時,只要找到集合中處在?標geohash?格中的第?個值,后續依次對?即可,不?多次查找。九宮格不能?起查,要?個個遍歷的原因也在于九宮格各?格對應的geohash值不具有連續性。只有連續了,查詢效率才會?,不然要多做許多距離運算。

總結

以上是生活随笔為你收集整理的【学习笔记】Redis的geohash数据结构介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。