Redis三種特殊資料型別API詳解附帶詳細使用場景

key2world發表於2020-12-03

geospatial(地理位置)

微信中朋友的定位,附近的人,叫車距離計算,這些都是怎麼實現的呢?

Redis的Geo 在Redis3.2版本就推出來了,這個功能可以推算地理位置的資訊,比如說兩地之間的距離,方圓幾裡的人。

可以查詢一些測試資料:城市地理位置經度緯度查詢http://www.jsons.cn/lngcode/

geoadd 新增地理位置

# 規則:兩極無法之間新增,一般會下載城市資料之間通過Python程式匯入
# 引數 key 值(緯度 經度 名稱)
# 有效的經度從-180度到180度。
# 有效的緯度從-85.05112878度到85.05112878度。 
# 當座標位置超出上述指定範圍時,該命令將會返回一個錯誤。

127.0.0.1:6379> geoadd china:city 116.40 39.90 beijing
(integer) 1
127.0.0.1:6379> geoadd china:city 127.47 31.23 shanghai
(integer) 1

geopos

獲得當前定位:一定是一個座標值。

# 獲取指定城市的經度和緯度
127.0.0.1:6379> geopos china:city beijing shanghai
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
2) 1) "127.47000128030776978"
   2) "31.22999903975783553"

geodist

兩人之間的距離

單位:

  • m 表示單位米
  • km 表示單位千米
  • mi 表示單位英里
  • ft 表示單位英尺
127.0.0.1:6379> geodist china:city beijing shanghai  # 檢視上海到北京的直線距離
"1388236.3971"
127.0.0.1:6379> geodist china:city beijing shanghai km  # 單位千米
"1388.2364"

georadius 以給定的經緯度為中心,找出某一半徑內的元素

我附近的人(獲得所有附近的人的地址,定位)通過半徑來查詢,獲得指定數量的人

所有的資料都應該錄入:china:city才會讓結果更加清晰。

127.0.0.1:6379> georadius china:city 110 30 2000 km  # 以110,30這個經緯度為中心,尋找方圓1000km內的城市
1) "shanghai"
2) "beijing"
127.0.0.1:6379> georadius china:city 110 30 2000 km withdist  # 顯示到中間距離的位置
1) 1) "shanghai"
   2) "1676.1046"
2) 1) "beijing"
   2) "1245.2858"
127.0.0.1:6379> georadius china:city 110 30 2000 km withcoord  # 顯示他人的定位資訊
1) 1) "shanghai"
   2) 1) "127.47000128030776978"
      2) "31.22999903975783553"
2) 1) "beijing"
   2) 1) "116.39999896287918091"
      2) "39.90000009167092543"
127.0.0.1:6379> georadius china:city 110 30 2000 km count 1  # 篩選出指定個數的使用者
1) "beijing"
127.0.0.1:6379> georadius china:city 110 30 2000 km count 2
1) "beijing"
2) "shanghai"

georadiusbymember

# 找出位於指定元素周圍的其他元素
127.0.0.1:6379> georadiusbymember china:city beijing 1000 km
1) "beijing"
127.0.0.1:6379> georadiusbymember china:city beijing 2000 km
1) "shanghai"
2) "beijing"

geohash 返回一個或多個位置元素的 Geohash 表示。很少使用

​ 該命令將返回11個字元的Geohash字串

# 將二維的經緯度轉換為一維的字串,如果兩個字串越相似則兩個位置越接近
127.0.0.1:6379> geohash china:city beijing shanghai
1) "wx4fbxxfke0"
2) "wvd9sthzfm0"

GEO底層的實現原理其實就是zset,我們可以使用zset命令來操作geo。

127.0.0.1:6379> zrange china:city 0 -1  # 檢視地圖中全部元素
1) "shanghai"
2) "beijing"
127.0.0.1:6379> zrem china:city beijing  # 移除指定元素
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1
1) "shanghai"

hyperloglog(基數)

什麼是基數?

A{1,3,5,7,8,7} B{1,3,5,7,8}

基數(不重複的元素)= 5,可以接受誤差

簡介

Redis2.8.9版本就更新了Hyperloglog資料結構

Redis Hyperloglog是用來做基數統計的演算法!

**優點:**佔用的記憶體是固定的,2^64不同的元素的計數,只需要費12kb的記憶體。如果要從記憶體角度來比較的話Hyperloglog就是首選。

網頁的UV(頁面訪問量,一個人訪問一個網站多次,但是還是算作一個人!)

傳統的方式,使用set儲存使用者的id,id一樣就會被覆蓋掉,然後就可以統計set中的元素數量作為標準判斷。這種方式如果儲存大量的id,就會比較麻煩,佔用大量記憶體。我們的目的是為了計數 ,而不是儲存使用者id。

0.81%的錯誤率,在統計UV任務中是可以忽略不計的。

測試使用

127.0.0.1:6379> pfadd mykey a b c d e f g h i  # 建立第一組元素 mykey
(integer) 1
127.0.0.1:6379> pfcount mykey  # 統計 mykey中元素的基數數量
(integer) 9
127.0.0.1:6379> pfadd mykey2 j k i a b z o  # 建立第二組元素 mykey2
(integer) 1
127.0.0.1:6379> pfcount mykey2  # 統計 mykey2中元素的基數數量
(integer) 7
127.0.0.1:6379> pfmerge mykey3 mykey mykey2  # 合併兩組mykey1 和 mykey2 -》mykey3 並集
OK
127.0.0.1:6379> pfcount mykey3  # 檢視並集的數量
(integer) 13

注:

​ 如果允許容錯,那麼一定可以使用hyperloglog。

​ 如果不允許容錯,就使用set 或者 自己的資料型別即可。

bitmap(點陣圖)

位儲存

統計使用者資訊,活躍,不活躍。登入,未登入。打卡,365打卡,userid status day(比較麻煩)。兩個狀態的都可以使用bitmap。

bitmaps 點陣圖,是一種資料結構。都是操作二進位制位來進行記錄,就只有0和1兩個狀態。

使用bitmaps記錄 週一到週日的打卡

週一:1:打卡 週二:0:未打卡 週三:1:打卡 週四:1:打卡

127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 1
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 0
(integer) 0
127.0.0.1:6379> setbit sign 5 0
(integer) 0
127.0.0.1:6379> setbit sign 6 0
(integer) 0

檢視某一天是否有打卡

127.0.0.1:6379> getbit sign 3
(integer) 1
127.0.0.1:6379> getbit sign 6
(integer) 0

統計操作,統計打卡的天數

127.0.0.1:6379> bitcount sign  # 統計這周的開啟記錄,就可以看到是否有全勤
(integer) 3

少年易老學難成,一寸光陰不可輕

相關文章