Redis 位圖基礎(chǔ)到統(tǒng)計(jì)活躍用戶

前言

大家有沒有想過如何統(tǒng)計(jì)活躍用戶數(shù)量?如果是自己做,那該怎么做?

這里思考一分鐘,后面我將分享一下如何使用 redis 中的位圖來統(tǒng)計(jì)活躍用戶數(shù)。

正文

什么是位圖 ?

位圖(bitmap) 是二進(jìn)制的 byte 數(shù)組,也可以簡單理解成是一個(gè)普通字符串。它將二進(jìn)制數(shù)據(jù)存儲在 byte 數(shù)組中以達(dá)到存儲數(shù)據(jù)的作用。

圖 1.1

如何使用位圖 ?

理清概念

在解釋什么是位圖的時(shí)候說過,位圖可以理解成是一個(gè)普通字符串,那么我們?yōu)槭裁匆梦粓D而不是字符串呢 ?

下面是在 redis 中存儲字符串的一個(gè)示意圖


圖 2.1

![setbit.png](https://upload-images.jianshu.io/upload_images/14961694-3ecf37534fa88624.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

如圖,存儲字符串是將字符串二進(jìn)制數(shù)組的形式存儲在 redis 中,位圖可以直接對 二進(jìn)制的數(shù)組操作,位圖的優(yōu)勢在于可以用 0 和 1來存儲布爾值,這大大降低了我們的存儲空間消耗。由于這個(gè)特性,我們用位圖來記錄簽到信息,記錄活躍用戶等,可以達(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

補(bǔ)充:上面說了位圖可以理解成字符串,那么它們之間可以互相操作嗎?

圖 2.2

請對照上圖,我們一起完成下面的探究:

  1. 以字符串存儲,可以通過 getbit 命令獲取到值嗎?

    我們可以結(jié)合查詢和圖片所示的 offset 及所對應(yīng)的值來驗(yàn)證

    > 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é)論:可以的

  2. 以字符串存儲,可以通過 settbit 修改值嗎?

    我們可以試著將 offset 7 對應(yīng)的 value 改成 1, 如果成功了,h 字符應(yīng)該變成 i

    > setbit str 7 1
    (integer) 0
    
    > get str
    "ii"
    

    結(jié)論:可以

  3. 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)用的項(xiàng)目中呢?

統(tǒng)計(jì)和查找

bitcount | bitpos

bitcount 是用來查找 1 出現(xiàn)的次數(shù),既可以對位圖使用也可以對字符串使用,用法如下:

bitcount [keyName] [startWith] [endWith]

注意:這里的 startWith 和 endWith 不是二進(jìn)制數(shù)組的下標(biāo)(offset)

這里的 startWith 和 endWith 可以理解成是字符串的下標(biāo),一個(gè)字符串對應(yīng) 8 位二進(jìn)制數(shù)據(jù);它們相當(dāng)于是截取字符串,如 s= "hi", s[0:0] = "h", 它所對應(yīng)的二進(jìn)制數(shù)組的下標(biāo)是 0,7,以此類推。

其實(shí)這里不好解釋,先來帶代碼,可以結(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è)置的時(shí)候默認(rèn)全部范圍

應(yīng)用場景:統(tǒng)計(jì)活躍用戶的數(shù)量

bitpos用來查找指定范圍內(nèi)出現(xiàn)的第一個(gè) 0 或 1,用法如下:

bitpos [keyName] [bit] [start] [end]

bit: 要找的 0 或者 1, start 和 end 同上面的 startWith 和 endWith

應(yīng)用場景:獲取第一次簽到和第一次未簽到的時(shí)間

應(yīng)用場景

上面大致說了 2 個(gè)應(yīng)用場景:

  1. 統(tǒng)計(jì)活躍用戶的數(shù)量
  2. 獲取第一次簽到和第一次未簽到的時(shí)間

我在這里稍微介紹一下思路,然后附上一個(gè) 統(tǒng)計(jì)活躍用戶的數(shù)量 可供參考

統(tǒng)計(jì)活躍用戶的數(shù)量

  1. 將位圖的 keyName 設(shè)置成需要統(tǒng)計(jì)的 行為和時(shí)間范圍 [ation:date], 如:login:2020-3
  2. 將用戶對應(yīng)到位圖中的 offset, 如 id 對應(yīng)二進(jìn)制數(shù)組的下標(biāo),idint
  3. 簽到成功使用 setbit 將對應(yīng)的offset 設(shè)置成 1
  4. 使用 bitcount 統(tǒng)計(jì)某個(gè)行為和時(shí)間范圍的活躍人數(shù),如 bitcount login:2020-3

Demo: DailyActiveUsers

獲取第一次簽到和第一次未簽到的時(shí)間

  1. 將位圖的 keyName 設(shè)置成需要統(tǒng)計(jì)的 行為和時(shí)間范圍和對象 [ation: date:person], 如:login:2020-3:Tom
  2. 將日期對應(yīng)到位圖中的 offset, 如 1號對應(yīng)二進(jìn)制數(shù)組的下標(biāo) 0, 2 號為 1
  3. 簽到成功使用 setbit 將對應(yīng)的offset 設(shè)置成 1
  4. 使用 bitpos 統(tǒng)計(jì)某個(gè)行為和時(shí)間范圍和對象的簽到情況,如 bitpos login:2020-3:Tom 1

總結(jié)

  1. 位圖和字符串沒有本質(zhì)上的區(qū)別,只是操作方式不同
  2. 使用位圖存儲布爾數(shù)據(jù)可以大大節(jié)省空間
  3. 存取命令 setbit/getbit
  4. 統(tǒng)計(jì)查找 bitcount / bitpos

最后

上述內(nèi)容對大家有所幫助的話,請幫我 點(diǎn)個(gè)贊??,分享不易,感謝支持!

如果本文有任何錯誤,感謝各位批評指教 !

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一億個(gè)用戶,有的用戶頻繁登錄,也有不經(jīng)常登錄的。如何記錄用戶的登錄信息?如何查詢活躍用戶?[如一周內(nèi) 登錄三次的]...
    小胖學(xué)編程閱讀 9,025評論 0 12
  • 基本的Redis key的操作都已經(jīng)熟悉了之后,便可以開始針對Redis提供的各種可操作的數(shù)據(jù)結(jié)構(gòu)進(jìn)行學(xué)習(xí)和了解。...
    Yorking閱讀 907評論 0 0
  • 什么是位圖 位圖(Bitmap)是通過一個(gè) bit 來表示某個(gè)元素對應(yīng)的值或者狀態(tài)。它并不是什么新的數(shù)據(jù)結(jié)構(gòu)。它的...
    youthcity閱讀 2,148評論 1 51
  • 一、大家覺得在PPT中什么樣的表格樣式才算美觀大方、重點(diǎn)突出。 二、美化表格四步驟如下: 001.去除格式 002...
  • #八歲日記#略凌亂~ 繼我回京一周后,老媽也結(jié)束了二十多天的杭州之行,啟程回家~昨天閑來無事一起翻看照片,又讓我想...
    妖八歲閱讀 311評論 0 0

友情鏈接更多精彩內(nèi)容