- 最近在项目中要用到一个签到
N
天送礼品的功能, 这个功能很自然而然的想到用Redis
的bitmap
去实现
- 签到就是
setbit {key} {offset} 1
- 累计签到天数就是
bitcount {key} {start} {end}
index.md
# 基数日期比如是: 2023-09-12, 那么 2023-09-12, offset 就是 0
setbit users:id 0 1
# 10000000
# 2023-09-13, offset 就是 1
setbit users:id 1 1
# 11000000
# 然后获取用户: 2023-09-12 ~ 2023-09-20 的登录天数, 当时代码就是
bitcount users:id 0 8
# 输出的也是 2, 当时也没想这么多. 然后测试的时候, 测试人员反馈当获取 2023-09-13 ~ 2023-09-20 的登录天数的时候一直是 0
bitcount users:id 1 7
# 输出的是 0, 实际上上面的命令是获取了`9~16 bit`的`1`数量, 11000000 由于后面无`1`, 所以 bitcount users:id 1 7 必定返回了 0
- 一开始下意识的认为, 以为
start,end
就是bit
, 然后查了文档才发现实际上是byte
, 所以在bitcount
的时候, 数据不对
旧版本解决方案
- 由于我们的
Redis
版本比较低的问题, 所以代码中计算的时候改成如下方案
set
的时候乘以8
,虽然导致浪费了7
倍的空间, 但是为了让代码简单点忍忍 (最好的方案还是升级Redis
来支持BIT
参数)
setbit {key} {offset*8} 1
bitcount {key} {start} {end}
Redis
大于7.0
版本解决方案
bitcount {key} {start} {end} BIT