【六月更文打卡】Redis学习笔记Day02 位图

36 阅读2分钟

何为位图(bitmap)

位图不是特殊的数据结构,它本身是一个普通字符串,即 byte 数组。一个 byte 使用 8 个二进制位存储。redis 提供一系列操作二进制位的指令操作,这些操作称为「位图操作」。

计算机存储单位有:bit、byte、KB、MB、GB、TB、ZB、EB、BB。bit 是计算机的最小存储单位,存储的都是 0 和 1;byte(字节)是计算机的最小数据处理单元,一个字母用一个 byte 存储,一个汉字用两个 byte 存储,1 Byte = 8 bit。
1 byte = 8bit 1 kb = 1024byte 1 mb = 1024kb ......

使用 getbit、setbit 可以直接对 value 的位进行操作,在处理数亿级别的业务标示位存储时能够节约很大的空间。

redis 中一个 String 类型的 value 能存储最大的值是 512MB、那么能存储大约 40亿 个bit。

512MB * 1024 = 524288KB
524288KB * 1024 = 536870912Byte
536870912Byte * 8 = 4294967296Bit

基本使用

零存零取 setbit / getbit

一个字符串的字节数组是其所有字符在 ASCII 码上的值。 he 的字节数组是 [104, 101],其二进制位体现是:(0)1101000 (0)1100101。

我们可以使用 bitset 指令以「位存储」的方式存储一个 he 字符串,注意上面获取的是无符号表示,存储的时候需要添加第一位为符号位。

127.0.0.1:6379> setbit he 0 0 # 添加符号位
(integer) 0
127.0.0.1:6379> setbit he 1 1
(integer) 0
127.0.0.1:6379> setbit he 2 1
(integer) 0
127.0.0.1:6379> setbit he 3 0
(integer) 0
127.0.0.1:6379> setbit he 4 1
(integer) 0
127.0.0.1:6379> setbit he 5 0
(integer) 0
127.0.0.1:6379> setbit he 6 0
(integer) 0
127.0.0.1:6379> setbit he 7 0
(integer) 0
127.0.0.1:6379> get he # “整取”
"h" # 设置了第一个字符
127.0.0.1:6379> setbit he 8 0 # 添加符号位
(integer) 0
127.0.0.1:6379> setbit he 9 1
(integer) 0
127.0.0.1:6379> setbit he 10 1
(integer) 0
127.0.0.1:6379> setbit he 11 0
(integer) 0
127.0.0.1:6379> setbit he 12 0
(integer) 0
127.0.0.1:6379> setbit he 13 1
(integer) 0
127.0.0.1:6379> setbit he 14 0
(integer) 0
127.0.0.1:6379> setbit he 15 1
(integer) 0
127.0.0.1:6379> get he # “整取”
"he" # 设置了两个字符
127.0.0.1:6379> getbit he 14 # “零取”
(integer) 0

统计和查找 bitcount / bitpos

  • bitcount key [start end]:统计指定范围内 1 出现的次数;
  • bitpos key bit [start] [end]:统计指定范围内 0 或 1 第一次出现的位置。

需要注意的是,这里的索引值是以 byte 为单位的,不是以 bit 为单位。即是以字节为范围查找的,如果需要以位范围查找必须是 8 的倍数。

批量操作 bitfield

bitfield 有三个子指令 set、get、incrby。他们可以对执行片段进行读写自增,最多处理 64 个连续位。