目录
背景
结构
存取方式
统计和查找
背景
开发过程中,会有布尔类型的存储,比如记录一个用户一年365天的签到情况,如果每天都要有一个布尔变量,多个用户,亦或者使用k-v形式,上亿用户的话这个存储量是惊人的。所以Redis的位图应运而生。
一个值占一个位,365天也就是365位,46个字符,也就是一个长点的字符串,大大节省了内存空间。
结构
它并不是一种类似于队列等的特殊的数据结构,内容其实就是普通的字符串,按二进制位数来说,也是就byte数组,可以使用,get,set索引来直接获取或者设置整个位图的内容。
Redis的为数组是自动扩展的,如果偏移位置超出了反胃,会自动扩容。
直接把字符串设置为“hello”,
hello的ASCⅡ码 :>>> bin(ord(' h '))'0b1101000'# 高位 -> 低位>>> bin(ord(' e '))'0b1100101'>>> bin(ord(' l '))'0b1101100'>>> bin(ord(' l '))'0b1101100'>>> bin(ord(' o '))'0b1101111'
注意都是八位。
设置一下一个字符串的位,只需要设置值为1 的位即可
127.0.0.1:6379> setbit s 1 1(integer) 0127.0.0.1:6379> setbit s 2 1(integer) 0127.0.0.1:6379> setbit s 4 1(integer) 0127.0.0.1:6379> setbit s 9 1(integer) 0127.0.0.1:6379> setbit s 10 1(integer) 0127.0.0.1:6379> setbit s 13 1(integer) 0127.0.0.1:6379> setbit s 15 1(integer) 0127.0.0.1:6379> get s"he"
h 只有 1 2 4位是1,e是 9 10 13 15位是1 (两个字符,16位 )直接得到便是一个“he”的字符串
存取方式
以上的例子可以理解为零存整取,还有零存零取,整存零取,零存就是向上面那样一位一位对位置进行设置。整存就是把字符串一次性填充所有位数组,覆盖旧值。
看完位图的结构和存储之后,我们存下来是为了获得统计数量,完成我们所需要的需求。
统计和查找
Redis提供了位图指令:bitcount 和 bitpos,
bitcount用来统计指定位置范围内1的个数,
bitpos 用来查找指定范围内出现的第一个0 或 1
后面参数[start, end] 但是这两个参数都是以8字节位单位的,也就是说,0, 1是指第一个开始第二个字节结束,范围实际上是前十六位。
127.0.0.1:6379> set w helloOK127.0.0.1:6379> bitcount w(integer) 21127.0.0.1:6379> bitcount w 0 0 # 第一个字符中 1 的位数(integer) 3127.0.0.1:6379> bitcount w 0 1 # 前两个字符中 1 的位数(integer) 7127.0.0.1:6379> bitpos w 0 # 第一个 0 位(integer) 0127.0.0.1:6379> bitpos w 1 # 第一个 1 位(integer) 1127.0.0.1:6379> bitpos w 1 1 1 # 从第二个字符算起,第一个 1 位(integer) 9127.0.0.1:6379> bitpos w 1 2 2 # 从第三个字符算起,第一个 1 位(integer) 17