位圖法
位圖(bitmap),就是用位(bit)來表示存放的某種狀態,如開關,有無。在redis中,字符串是以二進制的形式存儲的,因此位圖在redis中並不是一種數據類型,而是一種字符串的表現形式。位圖中每個元素在內存中佔用1位,所以可以節省存儲空間。
相關命令
1、SETBIT key offset value
該命令時間複雜度: O(1),效率極高;
對 key
所儲存的字符串值,設置或清除指定偏移量上的位(bit)。
位的設置或清除取決於 value
參數,可以是 0
也可以是 1
。
當 key
不存在時,自動生成一個新的字符串值。
字符串會進行伸展以確保它可以將 value
保存在指定的偏移量上。當字符串值進行伸展時,空白位置以 0
填充。
offset
參數必須大於或等於 0
,小於 2^32 (bit 映射被限制在 512 MB 之內)。
2、BITOP operation destkey key [key …]
該命令時間複雜度: O(N)
對一個或多個保存二進制位的字符串 key
進行位元操作,並將結果保存到 destkey
上。
operation
可以是 AND
、 OR
、 NOT
、 XOR
這四種操作中的任意一種:
-
BITOP AND destkey key [key ...]
,對一個或多個key
求邏輯並,並將結果保存到destkey
。 -
BITOP OR destkey key [key ...]
,對一個或多個key
求邏輯或,並將結果保存到destkey
。 -
BITOP XOR destkey key [key ...]
,對一個或多個key
求邏輯異或,並將結果保存到destkey
。 -
BITOP NOT destkey key
,對給定key
求邏輯非,並將結果保存到destkey
。
除了 NOT
操作之外,其他操作都可以接受一個或多個 key
作爲輸入。
3、BITCOUNT key [start] [end]
該命令時間複雜度: O(N)
計算給定字符串中,被設置爲 1 的比特位的數量。
一般情況下,給定的整個字符串都會被進行計數,通過指定額外的 start 或 end 參數,可以讓計數只在特定的位上進行。
start 和 end 參數的設置和 GETRANGE key start end 命令類似,都可以使用負數值: 比如 -1 表示最後一個字節, -2 表示倒數第二個字節,以此類推。
不存在的 key 被當成是空字符串來處理,因此對一個不存在的 key 進行 BITCOUNT 操作,結果爲 0 。
統計活躍用戶
爲了統計每日登錄的用戶數,建立了一個bitmap, 每一位標識一個用戶ID。
當某個用戶登錄了網站或執行了某個操作,就在bitmap中把標識此用戶的位置爲1,未登錄默認爲0,
然後進行and操作,即可統計活躍用戶數。
redis key可以設計成:時間周;
offset 用user_id。
用戶登錄數據如下:
100 、101、102、103 代表用戶user_id
週一:{100,101,102,103}
週二:{101,102,103}
週三:{101,102}
週四:{100,101,102}
週五:{100,101,102,103}
週六:{101,102,103}
週日:{100,101,102}
一週內連續登錄的用戶有2個:{101,102}
以下使用命令演示一週的用戶登錄情況:
localhost:6379:0>SETBIT mon 100 1
0
localhost:6379:0>SETBIT mon 101 1
0
localhost:6379:0>SETBIT mon 102 1
0
localhost:6379:0>SETBIT mon 103 1
0
localhost:6379:0>SETBIT tue 101 1
0
localhost:6379:0>SETBIT tue 102 1
0
localhost:6379:0>SETBIT tue 103 1
0
localhost:6379:0>SETBIT wed 101 1
0
localhost:6379:0>SETBIT wed 102 1
0
localhost:6379:0>SETBIT thu 100 1
0
localhost:6379:0>SETBIT thu 101 1
0
localhost:6379:0>SETBIT thu 102 1
0
localhost:6379:0>SETBIT fri 100 1
0
localhost:6379:0>SETBIT fri 101 1
0
localhost:6379:0>SETBIT fri 102 1
0
localhost:6379:0>SETBIT fri 103 1
0
localhost:6379:0>SETBIT sat 101 1
0
localhost:6379:0>SETBIT sat 102 1
0
localhost:6379:0>SETBIT sat 103 1
0
localhost:6379:0>SETBIT sun 100 1
0
localhost:6379:0>SETBIT sun 101 1
0
localhost:6379:0>SETBIT sun 102 1
0
統計一週內連續登錄用戶:
localhost:6379:0>BITOP AND result mon tue wed thu fri sat sun
13
localhost:6379:0>BITCOUNT result
2
使用 bitmap 實現用戶上線次數統計
假設現在我們希望記錄自己網站上的用戶的上線頻率,比如說,計算用戶 A 上線了多少天,用戶 B 上線了多少天,諸如此類,以此作爲數據,從而決定讓哪些用戶參加 beta 測試等活動 —— 這個模式可以使用 SETBIT key offset value 和 BITCOUNT key [start] [end] 來實現。
比如說,每當用戶在某一天上線的時候,我們就使用 SETBIT key offset value ,以用戶名作爲 key ,將那天所代表的網站的上線日作爲 offset 參數,並將這個 offset 上的value設置爲 1 。
舉個例子,如果今天是網站上線的第 100 天,而用戶 peter 在今天閱覽過網站,那麼執行命令 SETBIT peter 100 1 ;如果明天 peter 也繼續閱覽網站,那麼執行命令 SETBIT peter 101 1 ,以此類推。
當要計算 peter 總共以來的上線次數時,就使用 BITCOUNT key [start] [end] 命令:執行 BITCOUNT peter ,得出的結果就是 peter 上線的總天數。