-
对于开关 / 签到类型的业务数据,可以考虑采用
bitmap(即位图)的数据结构进行存储 -
位图的最小单元是
bit,每个 bit 的取值只能是 0 或 1,如下图所示:

-
Redis 字符位顺序与其 ASCII 码二进制值位顺序相反,多个字符会自动扩容连接在一起:

-
set整存,get整取,setbit零存,getbit零取:127.0.0.1:6379> set w he 127.0.0.1:6379> get w "he" 127.0.0.1:6379> setbit s 1 1 127.0.0.1:6379> setbit s 2 1 127.0.0.1:6379> setbit s 4 1 127.0.0.1:6379> setbit s 9 1 127.0.0.1:6379> setbit s 10 1 127.0.0.1:6379> setbit s 13 1 127.0.0.1:6379> setbit s 15 1 127.0.0.1:6379> getbit w 4 (integer) 1 127.0.0.1:6379> get s "he" -
bitcount命令统计指定位置范围内 1 的个数。
eg. 统计签到天数。起始参数[start, end]为索引值,必须为 8 的倍数。 -
bitpos命令查找指定范围内出现的第一个 0 或 1。
eg. 查找签到第一天。起始参数[start, end]为索引值,必须为 8 的倍数。 -
bitfield可以一次操作多个位,子指令get/set/incrby都可以对指定位片段进行读写,参数u为无符号,参数i为有符号。 -
bitfield处理上限为 64 个连续的位,否则需要执行子指令:127.0.0.1:6379> bitfield w get u4 0 get u3 2 get i4 0 get i3 2 1) (integer) 6 #index=0,无符号取 4 位 2) (integer) 5 #index=2,无符号取 3 位 3) (integer) 6 #index=0,有符号取 4 位 4) (integer) -3 #index=2,有符号取 3 位,注意负数的补码计算 -
Redis 的 integer 是有符号数,最大 64 位,不能传递 64 位无符号值,所以无符号值最大值为 63 位。
-
自增操作需要注意位数据溢出的问题:
- 无符号数自增溢出归零(eg.
u127+1=0) - 有符号数自增溢出变为最小负数(eg.
i127+1=-128)
- 无符号数自增溢出归零(eg.
-
bitfield提供另外两种溢出策略:- 饱和截断 SAT:停留在最大/最小值。
- 失败不执行 FAIL:报错不执行。