Redis从入门到放弃07——bitmap 数据类型

159 阅读5分钟

Redis从入门到放弃07——bitmap 数据类型

bitmap 数据类型介绍(官网原文)

Bitmaps are not an actual data type, but a set of bit-oriented operations defined on the String type which is treated like a bit vector. Since strings are binary safe blobs and their maximum length is 512 MB, they are suitable to set up to 2^32 different bits.

You can perform bitwise operations on one or more strings. Some examples of bitmap use cases include:

  • Efficient set representations for cases where the members of a set correspond to the integers 0-N.
  • Object permissions, where each bit represents a particular permission, similar to the way that file systems store permissions

bitmap 不是一种实际的数据类型,而是在String类型上定义的一组面向位的操作,它被视为位向量。由于字符串是二进制安全的blob,其最大长度为512 MB,因此它们适合设置最多2^32个不同的位。

您可以对一个或多个字符串执行按位操作。位图用例的一些例子包括:

集合的成员对应于整数0-N的有效集合表示。

对象权限,其中每个位代表一个特定的权限,类似于文件系统存储权限的方式


bitmap(位图) :实际是用string类型作为底层数据结构实现的一种统计二值状态的数据类型,本质是数组,它是基于String数据类型的按位的操作。该数组由多个二进制位组成,每个二进制位都对应一个偏移量(我们称之为一个索引)。一句话总结来说:bitmap 是由0和1状态表现的二进制位的bit数组。

Bitmap支持的最大位数是2^32位,它可以极大的节约存储空间,使用512M内存就可以存储多达42.9亿的字节信息(2^32 = 4294967296)

bitmap数据类型常用命令

查看bitmap数据类型下所有命令 :help @bitmap

127.0.0.1:6379> help @bitmap

  BITCOUNT key [start end [BYTE|BIT]]
  summary: Count set bits in a string
  since: 2.6.0

  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 ...]
  summary: Perform arbitrary bitfield integer operations on strings
  since: 3.2.0

  BITFIELD_RO key GET encoding offset [encoding offset ...]
  summary: Perform arbitrary bitfield integer operations on strings. Read-only variant of BITFIELD
  since: 6.2.0

  BITOP operation destkey key [key ...]
  summary: Perform bitwise operations between strings
  since: 2.6.0

  BITPOS key bit [start [end [BYTE|BIT]]]
  summary: Find first bit set or clear in a string
  since: 2.8.7

  GETBIT key offset
  summary: Returns the bit value at offset in the string value stored at key
  since: 2.2.0

  SETBIT key offset value
  summary: Sets or clears the bit at offset in the string value stored at key
  since: 2.2.0

#### GETBIT key offset:对 key 所储存的字符串值,获取指定位置的二进制位的值

127.0.0.1:6379> set foo bar
OK
127.0.0.1:6379> getbit foo 0
(integer) 0
127.0.0.1:6379> getbit foo 6
(integer)

bar的3个字母对应的ASCII码分别为98、97和114,转换成二进制后分别为1100010、1100001和1110010,所以foo键中的二进制位结构如图所示

Image.png (下标是从左往右)

BITCOUNT key [start end [BYTE|BIT]]:统计key在指定范围内的1的出现次数,0, -1或者不加参数表示统计全部

--从foo键中字符串 bar 的二进制位图可以看算出 1共有10127.0.0.1:6379> get  foo
"bar"
127.0.0.1:6379> bitcount foo 0 -1
(integer) 10

SETBIT key offset value:设置字符串类型键指定位置的二进制位的值。当key不存在时,将创建一个新的字符串值。字符串被加长以确保它能在偏移处保持一个位。offset参数必须大于或等于0,并且小于2^32(这将位图限制为512MB)。当key处的字符串增长时,添加的位被设置为0

127.0.0.1:6379> setbit foo 6 0
(integer) 1
127.0.0.1:6379> setbit foo 7 1
(integer) 0
127.0.0.1:6379> get foo
"aar"

BITOP operation destkey key [key ...]:对一个或多个保存二进制位的字符串key进行位元操作,并将结果保存到destksy上operation可以是AND、OR、NOT、XOR这四种操作中的任意一种

127.0.0.1:6379> setbit k1 0 1
(integer) 0
127.0.0.1:6379> setbit k1 1 0
(integer) 0
127.0.0.1:6379> setbit k1 2 0
(integer) 0
127.0.0.1:6379> setbit k1 3 0
(integer) 0
127.0.0.1:6379> setbit k1 4 1
(integer) 0
127.0.0.1:6379> setbit k2 0 0
(integer) 0
127.0.0.1:6379> setbit k2 1 1
(integer) 0
127.0.0.1:6379> setbit k2 2 0
(integer) 0
127.0.0.1:6379> setbit k2 3 0
(integer) 0
127.0.0.1:6379> setbit k2 4 1
(integer) 0
-- 与操作
127.0.0.1:6379> bitop and k3 k1 k2 
(integer) 1
127.0.0.1:6379> getbit k3 1
(integer) 0
-- 或操作
127.0.0.1:6379> bitop or k4 k1 k2
(integer) 1
127.0.0.1:6379> getbit k4 1
(integer) 1
-- 异或操作
127.0.0.1:6379> bitop xor k5 k1 k2
(integer) 1
127.0.0.1:6379> getbit k5 1
(integer) 1
-- 非操作
127.0.0.1:6379> bitop not k6 k1
(integer) 1
127.0.0.1:6379> getbit k6 1
(integer) 1

BITPOS key bit [start [end [BYTE|BIT]]]:统计key中指定范围内的bit(0或1)第一次出现的索引位置,没有则返回-1

127.0.0.1:6379> setbit k1 0 1
(integer) 0
127.0.0.1:6379> setbit k1 1 0
(integer) 0
127.0.0.1:6379> setbit k1 2 0
(integer) 0
127.0.0.1:6379> setbit k1 3 0
(integer) 0
127.0.0.1:6379> setbit k1 4 1
(integer) 0
127.0.0.1:6379> bitpos k1 0
(integer) 1
127.0.0.1:6379> bitpos k1 1
(integer) 0

STRLEN key:获取字符串的长度:这里字符串长度是指字符串占据几个字节,超过8位后自己按照8位一组一byte再扩容

127.0.0.1:6379> setbit k1 0 1
(integer) 0
127.0.0.1:6379> setbit k1 7 1
(integer) 0
127.0.0.1:6379> strlen k1
(integer) 1
127.0.0.1:6379> setbit k1 8 1
(integer) 0
127.0.0.1:6379> strlen k1
(integer) 2

应用场景

  • 用户是否登录过
  • 电影、广告是否被播放
  • 打卡上下班、签到统计等

案例一:统计001号员工一周内签到的次数

127.0.0.1:6379> setbit emp:001 0 1
(integer) 0
127.0.0.1:6379> setbit emp:001 1 1
(integer) 0
127.0.0.1:6379> setbit emp:001 2 0
(integer) 0
127.0.0.1:6379> setbit emp:001 3 1
(integer) 0
127.0.0.1:6379> setbit emp:001 4 0
(integer) 0
127.0.0.1:6379> setbit emp:001 5 1
(integer) 0
127.0.0.1:6379> setbit emp:001 6 1
(integer) 0
127.0.0.1:6379> bitcount emp:001 0 6
(integer) 5

案例二:统计两天连续都签到的员工


-- 添加员工:'0' 代表1号员工 '1' 代表2号员工
127.0.0.1:6379> hset uid:map 0 u1:login 1 u2:login
(integer) 2
127.0.0.1:6379> hgetall uid:map
1) "0"
2) "u1:login"
3) "1"
4) "u2:login"
-- 2023.07.211号员工签到 2号员工也签到
127.0.0.1:6379> setbit 20230721 0 1
(integer) 0
127.0.0.1:6379> setbit 20230721 1 1
(integer) 0
-- 2023.07.201号员工签到 2号员工未签到 
127.0.0.1:6379> setbit 20230720 0 1
(integer) 0
127.0.0.1:6379> setbit 20230720 2 1
(integer) 0
127.0.0.1:6379> bitop and allsigned 20230720 20230721
(integer) 1
127.0.0.1:6379> getbit allsigned 0
(integer) 1
127.0.0.1:6379> getbit allsigned 1
(integer) 0