位圖定義
位圖並不是一種數據結構,其實就是一種普通的字符串,也可以說是byte數組。基本語法是setbit/getbit,剛才說了是一個byte數組,所以也可以用set/get設置或獲取
SetBit語法: Setbit KEY_NAME OFFSET
GetBit語法: Getbit KEY_NAME OFFSET
應用場景
上面介紹了redis的位圖,對於redis位圖有什么應用場景?假如要統計用戶一年簽到次數,這里如果用記錄表來記錄的話,每個用戶就用存365條記錄,一千個用戶就是365*1000條記錄,想一下這個數據量是不少的,而且實際業務意義不是很明顯,那么有什么高效的方法可以替換?其實可以用本博客介紹的Redis位圖來實現,剛才說了位圖就是byte數字,假如簽到就表示1,沒簽到就表示0,這里可以用365個字節來記錄前端數,這樣很節省資源了,提高了效率。這個例子就是redis位圖的很好應用,比如用戶簽到統計,月活躍用戶數統計等等業務場景都適合用位圖實現
基本使用
Redis位圖的基本語法是setbit/getbit,按照一次只存一個字節,還是一次一個數組字符串整個存的情況,分為[零存整取]、[零存零取]、[整存零取],下面介紹的例子來自《Redis深度歷險:核心原理與應用實踐》一書
對於字符串'hello',換成ASCII碼的二進制為:
'h':0b1101000'
'e':0b1100101'
'l':0b1101100'
'l':0b1101100'
'o':'0b1101111'
[零存整取]的情況:setbit key為tk
//在第二位存“1”
127.0.0.1:6379> setbit tk 1 1
(integer) 0
//在第三位存"1"
127.0.0.1:6379> setbit tk 2 1
(integer) 0
//在第五位存"1"
127.0.0.1:6379> setbit tk 4 1
(integer) 0
//整個字節數組取出來
127.0.0.1:6379> get tk
"h"
127.0.0.1:6379>
[零存零取]的情況:
//在第二位加“1”位
127.0.0.1:6379> setbit tk 1 1
(integer) 1
//在第三位加“1”位
127.0.0.1:6379> setbit tk 2 1
(integer) 1
//在第五位加“1”為
127.0.0.1:6379> setbit tk 4 1
(integer) 1
//取出第二位
127.0.0.1:6379> getbit tk 1
(integer) 1
//取出第三位
127.0.0.1:6379> getbit tk 2
(integer) 1
//取出第五位
127.0.0.1:6379> getbit tk 4
(integer) 1
//取出第六位
127.0.0.1:6379> getbit tk 5
(integer) 0
127.0.0.1:6379>
[整存零取]
//存整個字符
127.0.0.1:6379> set tk h
OK
//獲取一下第二位
127.0.0.1:6379> getbit tk 1
(integer) 1
//獲取一下第三位
127.0.0.1:6379> getbit tk 2
(integer) 1
//獲取一下第五位
127.0.0.1:6379> getbit tk 4
(integer) 1
//獲取一下第六位
127.0.0.1:6379> getbit tk 5
(integer) 0
127.0.0.1:6379>
特殊情況:
127.0.0.1:6379> setbit tk 0 1
(integer) 1
127.0.0.1:6379> setbit tk 1 1
(integer) 1
//不代表任何字符,返回16進制符號
127.0.0.1:6379> get tk
"\xc0"
127.0.0.1:6379>
查找統計
Redis有提供查詢和統計函數,分別是bitpos和bitcount函數,其語法分別為:
bitcount語法:bitcount key [start end]
bitpos語法:bitpos key bit [start] [end]
127.0.0.1:6379> set tk hello
OK
//從第1個字符h算起,第一個“1”位的位置
127.0.0.1:6379> bitpos tk 1 1 1
(integer) 9
//從第2個字符2算起,第一個“1”位的位置
127.0.0.1:6379> bitpos tk 1 2 2
(integer) 17
//第一個“0”位
127.0.0.1:6379> bitpos tk 0
(integer) 0
//第一個“1”位
127.0.0.1:6379> bitpos tk 1
(integer) 1
//統計tk“1”的數量
127.0.0.1:6379> bitcount tk
(integer) 21
//第一個字符h的“1”位數量
127.0.0.1:6379> bitcount tk 0 0
(integer) 3
//第一個字符h和第二個字符e“1”位的數量
127.0.0.1:6379> bitcount tk 0 1
(integer) 7
127.0.0.1:6379>
