Redis笔记

做一些学习Redis的笔记

位图

基础操作

当我们开发的时候,有的数据只是作为一个标记进行存储,譬如说要记录一个用户在一个月内的签到的次数,如果我们每天都用一个key做记录的话,那么在用户量达到一个量时,需要的空间时非常惊人。

为了解决这个问题,redis提供了位图,实际上位图并不是特殊的数据结构,只是最简单的字符串,但是我们能对这个字符串的每个bit位进行操作。

如下我们获取到hello的二进制码,分别是’0b1101000’、‘0b1100101’ 、‘0b1101100’ 、‘0b1101100’ 、‘0b1101111’ ,我们知道 字母 h 的二进制码 其实是 01101000 ,此时我们在redis操作
redis操作bit
此时我们回到主题,如何来计算一个用户一个是否签到了多少天?

位图提供了统计字符的命令 bitcount。

此时我们将 s 设置为字符串 ‘hello’ 通过 bitcount 可以统计出里面有多少个1

bitcount统计数量
此外,我们还可以选定字符范围,(注意:这里是字符范围,不是字节范围)。
bitcount范围
如上,是统计了 hello 字符第1个和第2个字符包含了多好个0,也就是he包含了多少个1。bitcount s 0 0 也就是统计第1个字符也就是 h 包含了 多少个 1。

我们也可以通过bitpops可以查找到第一个0或者1的位置,但是范围参数依旧是按照字符范围进行计算的。
在这里插入图片描述
第一条命令的意思是 查找 s 中第一个 bit位为0的位置,第二条则是 为 1 的位置,第三条命令现在了字符范围 使用 0 0 限定为 第一个字符 ,第四条命令则限定为第三个字符。

那么,这样就存在一个问题。如果用户的签到记录从创建到目前均是放到一个字符串中进行记录的话,就不能明确统计某一特定时间段的次数,也就是说,如果上例中的 s 为某个用户一年内的签到记录,我们不能获取到5月份到6月份签到了多少次,必须读取到内存中再进行操作。

批量操作

对于基本的操作我们都是对每个位进行单独的操作,如果在操作的位比较多的情况下,这样操作是非常繁琐的。自Redis 3.2版本提供了一个功能强大的指令 bitfield。bitfield有三个子指令,分别是get/set/incrby,它们可以对指定的位片段进行独写,但是最多只能处理64个连续的位,如果超过了64位,就得使用多个指令,bitfield亦可以执行多个指令。

我们使用上面的 hello 字符串 执行如下命令
bitfield操作
第一条命令的意思是 从第0位开始取4个位作为无符号数(u),如例子 h的二进制码 是 01101000,那么第一条指令取到的就是 0110,结果就是6,第二条指令取到的是101,也就是5。值得注意的是,这里操作的就是bit位,而不是之前的字符byte了。第三条、第四条指令代表取出有符号数,首位将作为符号位,其余的作为值。
当然,能批量获取的话也就能批量设置,如下
bitfield set
表示将字符串s的第8位起8个位设置为97的值,结果s的值就变成了 hallo了。
接下来说到了incrby,它是对指定范围内的位进行自增操作,既然是自增操作,那么存在溢出的可能。如果增加了正数,那么会向上溢出,如果是负数,则会向下溢出,Redis默认的处理是折返,如果出现了溢出,就会将溢出的符号位丢掉。也就是说如果是8位的无符号数255,自增后将会变成0。如果是8位的有符号数127,自增后就会变成-128。
bitfield指令提供了溢出策略子指令overflow,用户可以选择溢出行为,默认是折返(wrap),还可以选择失败(fail) 报错不执行,以及饱和截断,超过了范围就停在最大最小值。overflow只影响接下来的第一条指令,这条指令执行完溢出策略后就会变成默认值折返(wrap)。
在这里插入图片描述
如上图可以看到,使用饱和截断的情况,当4位的无符号数自增到15的时候再自增1还是15。
我们再试一下,失败(fail)策略
fail策略
可以看到,在15的时候再自增直接不执行了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值