ps:读掘金小册笔记
位图的产生和作用
开发时我们常常需要存储一些bool型数据类型,比如用户的签到记录,签了为1,没签为0,如果用普通的key/value,每个用户要记录365个,当用户多的时候,需要的存储太多,为了解决这个问题,redis提供了位图数据结构,每天的签到记录只占据一个位,365天就是365位,也就是46个字节,其内容也是普通的字符串,也就是byte数组,可以用get,set获取和设置整个数组,也可以用getbite/setbite来将其作为数组来操作。
操作
setbit a 1 1;这个就是设置这个a这个数组第二位位1,getbite a 1,获取a这个byte数组的第二位的数字,如果直接用get a 则是获得到这个byte数组对应的Ascll值,用时我们也可以先set字符,然后getbite 其数组。总之,这2套操作是互通的。
统计查找
redis提供了位图统计指令bitcount和位图查找指令bitpos,bitcount是统计指定位置范围内1的个数,bitpos用来查找指定范围内出现的第一个0或者1。后面的2个参数指的是字符索引。比如bitcount w 0 0,表示w字节数组第一个字符中1的位数。比如bitcount w 0 1,则是查询前2个字符中1的位数。bitpos w 0,表示查询w这个字节数组第一个出现0的位置,bitpop w 1 2 2,表示查询第三个字符中第一个1出现的位置。
批量处理
1.前面getite都是单个单个执行的。如果想批量执行,就要用bitfield这个指令。
比如:bitfield w get u4 0,从第一个位置开始取4个数,结果是无符号数(u),bitfield w get i3 2,从第三个数开始取3个数,结果是有符号数(i).所谓有符号就是第一位是符号位,有符号数最多可以获取64位,无符号只能63位(redis协议中integer就是有符号数)
bitfield w set u8 8 97 这个就是把第二个字符改成a,因为a的ASCII码的值是97.这就可以批量修改字节数组的值。
bitfield w incrby u4 2 1 这个就是从第三个位开始,对接下来的无符号数+1,既然是自增操作,那么就可能出现溢出如果增加了正数就会上溢,如果增加的负数就会下溢出,redis默认的方法时折返,如果出现了溢出,就将溢出的符号位丢了。关于溢出,默认是折返
还有其他策略,饱和截断超过了范围就停留在最大值最小值那里,失败报错不执行。