Redis数据类型之位图Bitmap

本文最后更新于:2025年4月13日

想学习更多Redis相关知识,请点击右侧链接查看Redis学习笔记:点我查看

一、Redis位图(Bitmap)介绍

在正式讲解位图的概念之前,我们先来简单介绍一下位图中“位”是什么。

位(Bit,也称作比特)是计算机存储数据的最小单位,由二进制的0或1组成。

字节是一个由8个“位”的组合,一个字节可以表示256种不同的值(从00000000到11111111)。一个字节通常表示一个字符,例如:字母、数字、符号等。在ASCII编码中,每个字符通常使用1个字节表示。

“位”和字节之间的换算关系:

$$
1byte = 8bit
$$

Redis位图(Bitmap)是一种基于字符串(String)数据类型的操作方式,实际上是用二进制位(bit)来存储和操作数据。虽然位图在底层存储上只是普通的字符串,但我们可以将其视为超大的二进制数组:

为什么说位图本质上是字符串,我们可以使用Redis命令证明:

应用场景:

  • 签到打卡:假设一个月有31天,你可以为每个用户分配31个bit(位),1代表当天签到,0代表没有签到。

统计签到记录

  • 在线状态记录:使用位图可以用来记录每个用户的在线状态。假设一个网站有100万用户,可以使用位图来记录他们是否在线(在线就将对应的位设置为1,不在线将对应的位设置0),作为网站管理员,我们可以统计当前在线人数。

统计在线观看人数

  • 活动参与统计:可以使用位图记录用户是否参与过活动(例如:投票、抽奖等)。通过位图,可以快速判断某个用户是否参与。

抽奖活动统计

二、Redis位图(Bitmap)相关命令

1. 给指定的key第offset位赋值为value:

1
SETBIT key offset value

其中value对应的值只能是二进制的0和1。

该命令默认的返回值也是0和1。

这里解释一下为什么使用SETBIT命令时,返回0或1。这里我已上图中SETBIT myBitmap 3 1为例:

当我们在执行SETBIT myBitmap 3 1命令时,Redis会检查myBitmap的第3位(即offset = 3的位置)对应的值。如果符合以下任意一种情况,Redis会将该位置的默认值设置为0:

  • 当前位之前从未设置过值;
  • 对应的key不存在;

显然,在初次执行上述命令时,Redis中还不存在名为myBitmap的key,此时该位置的值默认是0。在执行SETBIT以后,Redis会将该位置的值设置为1,并返回执行SETBIT之前该位置对应的值(即0).

下面的动画演示这一过程:

2. 获取当前key第offset位的值:

1
GETBIT key offset

如果当前offset位置已经设置过值,使用GETBIT命令就可以获取到值(0或1)。如果当前位置没有设置过值,使用GETBIT命令得到的值是0。

3. 获取当前key在某个offset区间中值为1的数量:

1
BITCOUNT key [start end [BYTE | BIT]]

以下是命令各个参数的相关说明:

  • start(可选):统计的起始位置,可以是负数表示从末尾开始计算。
  • end(可选):统计的结束位置,同样可以是负数。
  • BYTE(可选):如果指定,startend参数以字节为单位(默认)。
  • BIT(可选):如果指定,startend参数以位为单位。

4. 对不同的二进制存储数据进行位运算(AND/OR/NOT/XOR)并存储到destkey中:

1
BITOP <AND | OR | NOT | XOR> destkey key [key ...]

AND是与运算,OR是或运算、NOT是非运算,XOR是异或运算,具体的计算方法详见这篇文章:点我查看

其中NOT运算比较特殊,因为它只能和一个key进行“非运算”操作。

一直ASCII码表中存储如下几个字符相关信息:

字符 二进制表示 十进制表示
a 01100001 97
b 01100010 98

以下是二进制运算过程:

5. 获取位图在内存中的存储大小:

1
STRLEN key

前面我们提到过,位图本质上是一个字符串,1个字符存储大小是1个字节,1个字节=8位:


Redis数据类型之位图Bitmap
https://www.icode504.com/posts/103.html
作者
iCode504
发布于
2025年4月13日
许可协议