Redis 高级数据结构 bitmap(位图)
简介:位图(bitmap)同样属于string数据类型。Redis中一个字符串类型的值最多能存储 512 MB 的内容,每个字符串由多个字节组成,每个字节又由 8 个Bit 位组成。位图结构正是使用“位”来实现存储的,它通过将比特位设置为0或1来达到数据存取的目的这大大增加了 value 存储数量,它存储上限为2^32 。位图本质上就是一个普通的字节串,也就是 bytes 数组。您可以使用getb
简介:
位图(bitmap)同样属于string数据类型。Redis中一个字符串类型的值最多能存储 512 MB 的内容,每个字符串由多个字节组成,每个
字节又由 8 个Bit 位组成。位图结构正是使用“位”来实现存储的,它通过将比特位设置为0或1来达到数据存取的目的这大大增加了 value
存储数量,它存储上限为2^32 。
位图本质上就是一个普通的字节串,也就是 bytes 数组。您可以使用getbit/setbit命令来处理这个位数组,位图的结构如下所示:
位图适用于一些特定的应用场景,比如用户签到次数、或者登录次数等。上图是表示一位用户 10 天内来网站的签到次数,1 代表签到,0 代表未签到,这样可以很轻松地统计出用户的活跃程度。相比于直接使用字符串而言,位图中的每一条记录仅占用一个 bit 位,从而大大降低了内存空间使用率。
位图常用命令
1) SETBIT命令
用来设置或者清除某一位上的值,其返回值是原来位上存储的值。key 在初始状态下所有的位都为 0 ,可以自动扩容,最大为40多个亿,语法格式如下:
SETBIT key offset value
其中 offset 表示偏移量,从 0 开始。示例如下:
127.0.0.1:6379> setbit k1 1 1
(integer) 0
127.0.0.1:6379> get k1
"@"
127.0.0.1:6379> STRLEN k1
(integer) 1
127.0.0.1:6379> setbit k1 7 1
(integer) 0
127.0.0.1:6379> get k1
"A"
127.0.0.1:6379> STRLEN k1
(integer) 1
127.0.0.1:6379> setbit k1 9 1
(integer) 0
127.0.0.1:6379> get k1
"A@"
127.0.0.1:6379> STRLEN k1
(integer) 2
2) GETBIT命令
用来获取某一位上的值。语法格式如下:
GEIBIT KEY OFFSET
示例如下:
127.0.0.1:6379> GETBIT K1 1
(integer) 1
当偏移量 offset 比字符串的长度大,或者当 key 不存在时,返回 0。
127.0.0.1:6379> GETBIT k1 100000 超过字符串长度
(integer) 0
127.0.0.1:6379> GETBIT k2 0 key不存在
(integer) 0
3) BITCOUNT命令
一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。
start 和 end 参数的设置,都可以使用负数值:比如 -1 表示最后一个位,而 -2 表示倒数第二个位,
start、end 是指bit组的字节的下标数,二者皆包含。
如上 K1 【01000001 01000000 00000000 00100001】,对应【0,1,2,3】
bitcount K1 1 2 : 统计下标1、2字节组中bit=1的个数,即01000000 00000000。
语法格式如下:
BITCOUNT key [start end]
示例如下:
127.0.0.1:6379> setbit k1 1 1
(integer) 0
127.0.0.1:6379> setbit k1 7 1
(integer) 0
127.0.0.1:6379> setbit k1 9 1
(integer) 0
127.0.0.1:6379> get k1
"A@"
127.0.0.1:6379> BITCOUNT k1 0 0 获取字节索引为1 1的个数
(integer) 2
127.0.0.1:6379> BITCOUNT k1 0 1 获取字节索引为1-2 1的个数
(integer) 3
通过指定的 start 和 end 参数,可以让计数只在特定的字节上进行。start 和 end 参数和 GETRANGE 命令的参数类似,都可以使用负数,比如 -1 表示倒数第一个位, -2 表示倒数第二个位。
4) .bitpos返回指定值0或者1在指定区间上首次出现的下标
语法:BITPOS key bit [start] [end](字节索引,0表示第一个字节)
summary: Find first bit set or clear in a string
since: 2.8.7
group: string
不指定查找范围,表示从全部内容中查找:BITPOS key bit
127.0.0.1:6379> BITPOS k1 1
(integer) 1
127.0.0.1:6379> setbit k1 1 0
(integer) 1
127.0.0.1:6379> BITPOS k1 1
(integer) 7
红色位为setbit 修改的地方,绿色位修改完成的地方
BITPOS key bit start :从start+1个字节开始查找,直到尾部
BITPOS key bit start end:从start+1字节开始到end+1字节之间查找
127.0.0.1:6379> setbit k1 1 1
(integer) 0
127.0.0.1:6379> BITPOS k1 1 0
(integer) 1
127.0.0.1:6379> BITPOS k1 1 2 0 找不到返回-1
(integer) -1
5).bitop位操作
语法:BITOP operation destkey key [key ...]
summary: Perform bitwise operations between strings
since: 2.6.0
group: string
对一个或多个保存二进制位的字符串 key 进行位操作,并将结果保存到 destkey 上。operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种
BITOP AND destkey key [key ...] ,对一个或多个 key 求逻与,并将结果保存到 destkey
BITOP OR destkey key [key ...] ,对一个或多个 key 求逻辑或,并将结果保存到 destkey
BITOP XOR destkey key [key ...] ,对一个或多个 key 求逻辑异或,并将结果保存到 destkey
BITOP NOT destkey key ,对给定 key 求逻辑非,并将结果保存到 destkey
除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入,当 BITOP 处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作 0,空的 key 也被看作是包含 0 的字符串序列。
BITOP AND destkey key [key ...]
演示:
127.0.0.1:6379> setbit k1 1 1
(integer) 0
127.0.0.1:6379> setbit k2 7 1
(integer) 0
127.0.0.1:6379> BITOP and andkey k1 k2
(integer) 1
127.0.0.1:6379> get andkey
"\x00"
全为1则为1,否则为0
BITOP OR destkey key [key ...]
演示:
127.0.0.1:6379> bitop or orkey k1 k2
(integer) 1
127.0.0.1:6379> get orkey
"A"
全为0则为0,否则为1
BITOP XOR destkey key [key ...]
演示:
127.0.0.1:6379> bitop xor xorkey k1 k2
(integer) 1
127.0.0.1:6379> get xorkey
"A"
不同为1,相同为0
BITOP NOT destkey key
演示:
127.0.0.1:6379> bitop not notkey k1
(integer) 1
127.0.0.1:6379> get notkey
"\xbf"
按位取反
Bitmaps优势
假设网站有1亿用户,每天独立访问的用户有5千万,如果每天用集合类型和 Bitmaps分别存储活跃用户,很明显,假如用户id是Long型,64位,则集合类型占据的空间为64位x50 000 000= 400MB,而Bitmaps则需要1位×100 000 000=12.5MB,可见Bitmaps能节省很多的内存空间。
举例:1、普通字符串操作
更多推荐
所有评论(0)