一、为什么使用位图?
使用位图能有效实现 用户签到 等行为,用数据库表记录签到,将占用很多存储;但使用 位图BitMap,就能 大大减少存储占用
二、关于位图
本质上是String类型,最小长度8位(一个字节),位数不够表示则扩容,每次扩容以字节为单位,最大占用内存为512MB,用来操作位
三、操作
引言:由于偏移量offset与数组下标结果一致,这里我就将offset当成二进制数组下标来讲解
1)设置二进制数组中指定下标的值
语法: | setbit key offset value |
---|---|
字段描述: | |
offset: | 二进制数组中相对于0号位置的偏移量(或者下标) |
value: | 给指定下标设置的值(0或1) |
设置val 二进制数组中下标为0的位置值为1(设置完后二进制数组为 10000 0000),如:
setbit val 0 1
2)获取指定下标的值
语法: | getbit key offset |
---|---|
字段描述: | |
offset: | 二进制数组中相对于0号位置的偏移量(或者下标) |
获取val 二进制数组中下标为0位置的值,如:
getbit val 0
3)统计1的数量
语法: bitcount key
4)查询指定值第一次出现的下标
语法: | bitpos key value |
---|---|
字段描述: | |
value: | 指定的值(0或1) |
5)多个二进制数组进行位运算
语法: | bitop and | or | xor | not destkey key1 key2 ... |
---|---|
作用: | 将这些key进行位运算(不包含destkey),运算的结果放到destkey中 |
字段描述: | |
destkey: | 存放的位置 |
key*: | 所有进行位运算的二进制数组 |
and | or | xor | not: | and,与;or或;xor,异或;not,非 |
6)取出二进制数组中指定范围的数据转换为十进制返回
语法: | bitfield_ro key [get type offset] ... |
---|---|
作用: | 取出部分二进制数据,如0011 1100,取出0011返回(0011转为十进制为3) |
字段描述: | |
type: | 第一个位置表示类型:i代表有符号整数(最高位0为正,1为负),u代表无符号整数;后面紧接着取出位的数量;如u5,代表从起始位置取出5位表示无符号整数 |
offset: | 起始偏移量(或起始下标) |
假如num 的二进制形式为0011 1100,从下标为2的位置,取出4位,作为无符号整数返回(十进制结果为15)
bitfield_ro num get u4 2
7)操作二进制数组中指定范围的数据
语法: | bitfield key [get type offset] [set type offset value] [incrby type offset value] |
---|---|
作用: | 操作部分二进制数据 |
字段描述: | |
type: | 第一个位置表示类型:i代表有符号整数(最高位0为正,1为负),u代表无符号整数;后面紧接着操作位的数量; |
offset: | 起始偏移量(或起始下标) |
value: | 要操作的值,可以是任意值 |
① bitfield key [get type offset]
作用:获取二进制数组中连续某一部分的数据转换为十进制
假如num 的二进制形式为0011 1100,从下标为2的位置,取出4位,作为无符号整数返回(十进制结果为15)
bitfield num get u4 2
② bitfield key [set type offset value]
作用:将指定部分的二进制数据的十进制形式设置为value,如果位数不够,则取最后几位;
假如num二进制为0011 1100 ,设置下标从1开始,数3位,也就是011,将8(二进制1000)赋值到这三位上,就成了000,那么num将变为0000 1100 ,操作如下:
bitfield num get u4 2
③ bitfield key [incrby type offset value]
作用:将指定部分的二进制数据加上value,保留原先长度个位
假如num二进制为0011 1100 ,那么取出下标2到3位置数据为11,转换为十进制为3,value为10,那么相加的结果就为13(二进制为1101),保留两位为01,用01替换原来的10,那么num的二进制结果为0001 1100,操作如下:
bitfield num incrby u2 2 10