前言
大家有沒有想過如何統(tǒng)計活躍用戶數(shù)量?如果是自己做煤杀,那該怎么做诀紊?
這里思考一分鐘谒出,后面我將分享一下如何使用 redis 中的位圖來統(tǒng)計活躍用戶數(shù)。
正文
什么是位圖 邻奠?
位圖(bitmap) 是二進(jìn)制的 byte 數(shù)組笤喳,也可以簡單理解成是一個普通字符串。它將二進(jìn)制數(shù)據(jù)存儲在 byte 數(shù)組中以達(dá)到存儲數(shù)據(jù)的作用碌宴。
如何使用位圖 杀狡?
理清概念
在解釋什么是位圖的時候說過,位圖可以理解成是一個普通字符串贰镣,那么我們?yōu)槭裁匆梦粓D而不是字符串呢 呜象?
下面是在 redis 中存儲字符串的一個示意圖
如圖,存儲字符串是將字符串二進(jìn)制數(shù)組的形式存儲在 redis 中八孝,位圖可以直接對 二進(jìn)制的數(shù)組操作董朝,位圖的優(yōu)勢在于可以用 0 和 1來存儲布爾值,這大大降低了我們的存儲空間消耗干跛。由于這個特性子姜,我們用位圖來記錄簽到信息,記錄活躍用戶等楼入,可以達(dá)到節(jié)省空間的能力(后面會有介紹)哥捕。
那我們?nèi)绾螌ΧM(jìn)制的數(shù)組進(jìn)行操作呢?
基本存取
setbit | getbit
上文說的二進(jìn)制數(shù)組我們可以對它做添加嘉熊、查找及修改的功能
如何進(jìn)行添加和查找呢?
setbit [keyName] [offset] [value]
offset:偏移量遥赚,指的是數(shù)組的下標(biāo); value: 數(shù)據(jù)阐肤, 只能是 0 和 1凫佛。
這條命令既可以添加數(shù)據(jù)也可以修改數(shù)據(jù)讲坎。
如何進(jìn)行查找呢 ?
getbit [keyName] [offset]
offset:偏移量愧薛,指的是數(shù)組的下標(biāo)晨炕。這里,除了設(shè)置 value 為 1 的 offset, 查詢其他的都返回 0
補充:上面說了位圖可以理解成字符串毫炉,那么它們之間可以互相操作嗎瓮栗?
請對照上圖,我們一起完成下面的探究:
-
以字符串存儲,可以通過
getbit
命令獲取到值嗎?我們可以結(jié)合查詢和圖片所示的 offset 及所對應(yīng)的值來驗證
> set str hi OK > getbit str 0 (integer) 0 > getbit str 4 (integer) 1 > getbit str 7 (integer) 0 > getbit str 15 (integer) 1
結(jié)論:可以的
-
以字符串存儲憋他,可以通過
settbit
修改值嗎?我們可以試著將 offset 7 對應(yīng)的 value 改成 1愿阐, 如果成功了,h 字符應(yīng)該變成 i
> setbit str 7 1 (integer) 0 > get str "ii"
結(jié)論:可以
-
用
setbit
存儲字符串的二進(jìn)制數(shù)據(jù)趾疚,可以通過get
獲取字符串嗎换况?我們將 字符 h 的二進(jìn)制存入位圖,看可以能通過 get 獲取
> setbit bitmap 0 0 (integer) 0 > setbit bitmap 1 1 (integer) 0 > setbit bitmap 2 1 (integer) 0 > setbit bitmap 3 0 (integer) 0 > setbit bitmap 4 1 (integer) 0 > setbit bitmap 5 0 (integer) 0 > setbit bitmap 6 0 (integer) 0 > setbit bitmap 7 0 (integer) 0 > get bitmap "h"
結(jié)論:可以
上面介紹了位圖的基本概念和使用盗蟆,通過一系列的探究希望能幫助大家更好的理解位圖
那么戈二,如何將位圖應(yīng)用的項目中呢?
統(tǒng)計和查找
bitcount | bitpos
bitcount
是用來查找 1 出現(xiàn)的次數(shù)喳资,既可以對位圖使用也可以對字符串使用觉吭,用法如下:
bitcount [keyName] [startWith] [endWith]
注意:這里的 startWith 和 endWith 不是二進(jìn)制數(shù)組的下標(biāo)(offset)
這里的 startWith 和 endWith 可以理解成是字符串的下標(biāo),一個字符串對應(yīng) 8 位二進(jìn)制數(shù)據(jù)仆邓;它們相當(dāng)于是截取字符串鲜滩,如 s= "hi"
, s[0:0] = "h"
, 它所對應(yīng)的二進(jìn)制數(shù)組的下標(biāo)是 0,7节值,以此類推徙硅。
其實這里不好解釋,先來帶代碼搞疗,可以結(jié)合著上面的 圖 2.2 看一下嗓蘑,大家后面可以在領(lǐng)悟一下
> set str hi
> bitcount str 0 0
(integer) 4
> bitcount str 0 1
(integer) 8
> bitcount str
(integer) 8
注意:startWith 和 endWith 不設(shè)置的時候默認(rèn)全部范圍
應(yīng)用場景:統(tǒng)計活躍用戶的數(shù)量
bitpos
用來查找指定范圍內(nèi)出現(xiàn)的第一個 0 或 1,用法如下:
bitpos [keyName] [bit] [start] [end]
bit: 要找的 0 或者 1匿乃, start 和 end 同上面的 startWith 和 endWith
應(yīng)用場景:獲取第一次簽到和第一次未簽到的時間
應(yīng)用場景
上面大致說了 2 個應(yīng)用場景:
- 統(tǒng)計活躍用戶的數(shù)量
- 獲取第一次簽到和第一次未簽到的時間
我在這里稍微介紹一下思路桩皿,然后附上一個 統(tǒng)計活躍用戶的數(shù)量 可供參考
統(tǒng)計活躍用戶的數(shù)量
- 將位圖的 keyName 設(shè)置成需要統(tǒng)計的 行為和時間范圍 [ation:date], 如:
login:2020-3
- 將用戶對應(yīng)到位圖中的
offset
, 如id
對應(yīng)二進(jìn)制數(shù)組的下標(biāo),id
為int
- 簽到成功使用
setbit
將對應(yīng)的offset
設(shè)置成 1 - 使用
bitcount
統(tǒng)計某個行為和時間范圍的活躍人數(shù)幢炸,如bitcount login:2020-3
Demo: DailyActiveUsers
獲取第一次簽到和第一次未簽到的時間
- 將位圖的 keyName 設(shè)置成需要統(tǒng)計的 行為和時間范圍和對象 [ation: date:person], 如:
login:2020-3:Tom
- 將日期對應(yīng)到位圖中的
offset
, 如 1號對應(yīng)二進(jìn)制數(shù)組的下標(biāo) 0泄隔, 2 號為 1 - 簽到成功使用
setbit
將對應(yīng)的offset
設(shè)置成 1 - 使用
bitpos
統(tǒng)計某個行為和時間范圍和對象的簽到情況,如bitpos login:2020-3:Tom 1
總結(jié)
- 位圖和字符串沒有本質(zhì)上的區(qū)別宛徊,只是操作方式不同
- 使用位圖存儲布爾數(shù)據(jù)可以大大節(jié)省空間
- 存取命令 setbit/getbit
- 統(tǒng)計查找 bitcount / bitpos
最后
上述內(nèi)容對大家有所幫助的話佛嬉,請幫我 點個贊??逻澳,分享不易,感謝支持暖呕!
如果本文有任何錯誤赡盘,感謝各位批評指教 !