小白都能看懂的Redis进阶篇--特殊的数据类型Bitmaps

139 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情

Bitmaps本身并不是一种数据结构,实际上它是一种字符串,如下图所示。
比较特别的的是Bitmaps可以对指定位数进行操作
它拥有自己的一套命令,可以把Bitmaps看作一个数组,这个数组的每个位置只能存储0或1,数组的下标在Bitmaps中称作偏移量

image.png

我们先看看Bitmaps的命令

1.1 设置值

setbit key offset value 命令可以设置第offset位的值。

127.0.0.1:6379> setbit name 1 0
(integer) 1

1.2 获取值

getbit key offset命令可以用来获取值

127.0.0.1:6379> getbit name 1
(integer) 0

1.3 获取指定范围内1的个数

bitcount key [start end]可以查询指定范围内1的个数

127.0.0.1:6379> bitcount name
(integer) 17

1.4 Bitmaps的运算

bitop op destkey key [key...]是一个复合操作,其中op可以是以下值

  • and 交集
  • or 并集
  • not 非
  • xor 异或

然后会把计算的结果保存到destkey中

1.5 计算指定范围内第一个0或1的偏移量

bitpos key target [start] [end]

上边之后的都没举例子,我们举一个帅气的例子说明一下集体用法。

一个帅气的例子

首先

比如我们的产品是一个商城,我们会把每天访问的客户统计起来作为优质客户定期推送优惠卷等增大用户粘性。

比较尴尬的是我们的用户Id虽然是自增的但是是从10000001开始的,若是直接从这个偏移量开始,岂不是前边的浪费了,初始化还贼慢。

所以我们可以用用户id减去10000001这个值,这样第一个用户的id就变成了0,刚好从第一个开始。

然后

2022-10-06这一天编号为0的用户访问了。

setbit users:2022-10-06 0 1

若是同一天有其他用户访问,则继续

setbit users:2022-10-06 66 1
setbit users:2022-10-06 105 1

这样就可以把每天的数据记录为一个key为日期的bitmaps。可以很快速的查出某天有哪些用户访问了

getbit users:2022-10-06 66

这时候重点来了。

想看看某天有多少用户访问了我们的商城:

bitcount users:2022-10-06 

比如十一刚完,我们想看看有哪些用户在十一的前三天访问了我们的商城,将这三天的数据求并集。

bitop and user:2022-10-01-03 user:2022-10-01 user:2022-10-02 user:2022-10-03

结果会保存到user:2022-10-01-03里边,方便查询。

那么若是只要在这三天登陆过一次就算数的,我们将送出大礼,那么可以这样计算,将这三天的数据求交集。

bitop or user:2022-10-01-03-or user:2022-10-01 user:2022-10-02 user:2022-10-03

这时候,我们有这样一个想法,给在系统中注册最早,在10月1还活跃的用户送出大礼,我们可以这样操作:

bitpos user:2022-10-01 1

这样将返回,登录了的用户,偏移量最小的一个。

不适合的情况

但是若是用户很多,比如有100万个,但是每天访问的很少只有100左右,每天都要初始化并维护很长一个bitmaps,这样其实是得不偿失的。