bitmap类型相关命令
由0和1状态表现的二进制位的bit数组。
应用场景:可用于京东签到送京豆,电影广告是否被点击,钉钉打卡、签到统计等
1. 位图概述
说明: 位图本质是数组,它是基于String数据类型的按位的操作。该数组由多个二进制位组成,每个二进制位都对应一个偏移量(我们称之为一个索引), Bitmap支持的最大位数是2^32位,它可以极大的节约存储空间,使用512M内存就可以存储多达42.9亿的字节信息(2^32=4294967296)。
2. SETBIT命令
语法: SETBIT key offset value
对bitmap上存储的0或1,分别表示设置或清除指定偏移量上的bit位, offset
需要大于等于0,但不能超过2^32,offset
每偏移8那么位图的字符串长度就增长1位, 命令执行返回二进制位被设置之前的旧值作为结果。
127.0.0.1:6379> setbit mykey 3 1
(integer) 0
127.0.0.1:6379> getbit mykey 3
(integer) 1
127.0.0.1:6379> strlen mykey
(integer) 1
127.0.0.1:6379> setbit mykey 8 1
(integer) 0
127.0.0.1:6379> strlen mykey
(integer) 2
3. GETBIT命令
语法: GETBIT key offset
获取指定offset在位图上面的值。offset大于0,如果位图不存在或者超过设置范围,都返回0。
127.0.0.1:6379> getbit mykey 3
(integer) 1
127.0.0.1:6379> getbit mykey -1
(error) ERR bit offset is not an integer or out of range
4. BITCOUNT命令
语法: BITCOUNT key [start end [BYTE | BIT]]
统计位图中设置的bit的个数, 默认情况下,扫描字符串中包含的所有字节, 参数start
和 stop
默认表示字节的起始和结束位置,以0表示第1个字节位置,以1表示第2个字节位置,以此类推。也可以使用负数表示字节位置,以 -1表示最后一个字节位置, -2表示倒数第二个字节位置,和SETBIT
中的offset
不同,offset
是二进制bit偏移量, 若命令加上BIT
参数,那么start
和 stop
表示bit的位置,和SETBIT
中的offset
相同。
127.0.0.1:6379> setbit uid:login123 1 1
(integer) 0
127.0.0.1:6379> setbit uid:login123 2 1
(integer) 0
127.0.0.1:6379> setbit uid:login123 3 1
(integer) 0
127.0.0.1:6379> setbit uid:login123 9 1
(integer) 0
127.0.0.1:6379> bitcount uid:login123
(integer) 4
## 第一周的登陆签到次数方式1:一天为一个bit位
127.0.0.1:6379> bitcount uid:login123 0 6 bit
(integer) 3
## 第一周的登陆签到次数方式2:一个字节占8位,一个字节可以记录一周零1天, 第一周都在第一字节里面)
127.0.0.1:6379> bitcount uid:login123 0 0 byte
(integer) 3
应用场景: 统计受欢迎程度
5. BITOP命令
语法: BITOP <AND | OR | XOR | NOT> destkey key [key ...]
对一个或多个位图执行指定的二进制位运算,并将运算结果存储到指定的destkey
中。 BITOP
支持4种按位操作,参数说明:
AND
: 逻辑与运算,允许任意数量的位图作为输入OR
: 逻辑或运算,允许任意数量的位图作为输入XOR
: 逻辑异或运算,允许任意数量的位图作为输入NOT
: 逻辑非运算,只允许使用一个位图作为输入
127.0.0.1:6379> bitop and test test1 kk1
(integer) 1
127.0.0.1:6379> bitcount test
(integer) 2
6. BITPOS命令
语法: BITPOS key bit [start [end [BYTE | BIT]]]
可以通过执行BITPOS命令,在位图中查找第一个被设置为指定值的二进制位(只能是0或者1),并返回这个二进制位的偏移量。若加上start
、end
表示从指定字节位置去获取偏移量。也可以使用负数表示字节位置,以-1表示最后一个字节位置,-2表示倒数第二个字节位置。如果位图不存在返回-1。若命令加上BIT
参数,那么start
和 end
表示bit的位置
127.0.0.1:6379> bitpos mykey 1 0 -1
(integer) 3
127.0.0.1:6379> bitpos all_8bit_0 0 1 -2 byte
(integer) -1
127.0.0.1:6379> bitpos all_8bit_1 0
(integer) 8
提示
bitpos all_8bit_1 0
之所以会返回8,是因为它在对位图中偏移量从0到7的8个二进制位进行检查之后,都没有找到值为0的二进制位,于是它继续移动指针,尝试去检查偏移量为8的二进制位,但是由于偏移量8已经超出了位图的有效偏移量范围,而Redis又会把位图中不存在的二进制位的值看作0,所以BITPOS命令最后就把偏移量8作为结果返回给用户。
7. BITFIELD命令
语法: BITFIELD key [GET encoding offset | [OVERFLOW <WRAP | SAT | FAIL >]
<SET encoding offset value | INCRBY encoding offset increment>
[GET encoding offset | [OVERFLOW <WRAP | SAT | FAIL >]
<SET encoding offset value | INCRBY encoding offset increment>
...]]
允许用户在位图中的任意区域(field
)存储指定长度的整数值,并对这些整数值执行加法或减法操作。
参数说明:
GET <encoding> <offset>
: 返回指定偏移量的二进制位的值。SET <encoding> <offset> <value>
: 设置值到指定的位置并返回旧的值INCRBY <encoding> <offset> <increment>
: 增加或者减少bit位数并返回新的值OVERFLOW [WRAP|SAT|FAIL]
: 配合INCRBY
或者SET
使用,用来控制发生溢出时的行为。WRAP
表示溢出就重新从0开始递增,SAT
表示溢出就保持溢出前最大值,FAIL
表示操作失败,旧数据不变。
其中encoding
表示参数的值需要以i或者u为前缀,后跟被设置值的位长度,其中i表示被设置的值为有符号整数,而u则表示被设置的值为无符号整数。比如i8表示被设置的值为有符号8位整数,而u16则表示被设置的值为无符号16位整数,Redis最大支持有符号整数最多为64位即i64,对于无符号整数最多为63位即u63。offset
参数用于指定设置的起始偏移量,或者用指定索引(字节)位置,用#索引
和offset
等效。value
参数用于指定被设置的整数值,这个值的类型应该和encoding
参数指定的类型一致。
127.0.0.1:6379> bitfield bitmap1 set u8 0 198 set i9 100 12000
1) (integer) 0
2) (integer) 0
127.0.0.1:6379> bitfield bitmap1 get u8 0 get i20 100
1) (integer) 198
2) (integer) 12000
127.0.0.1:6379> bitfield bitmap3 set u8 #0 125 set i10 #1 365 set i63 #3 360
1) (integer) 0
2) (integer) 0
3) (integer) 0
127.0.0.1:6379> bitfield bitmap3 incrby u8 #0 125
1) (integer) 250
127.0.0.1:6379> bitfield bitmap3 get u8 #0
1) (integer) 250
127.0.0.1:6379> bitfield bitmap3 OVERFLOW wrap incrby u8 #0 1250000
1) (integer) 202
127.0.0.1:6379> bitfield bitmap3 get u8 #0
1) (integer) 202