redis中bitmap的使用及场景,如何操作

本文介绍了Redis中的Bitmap数据结构,其基于String类型实现,用于高效存储大量二进制位。文章详细阐述了存储原理,提供了丰富的操作命令,并讨论了其在内存效率方面的优点,以及在签到统计等场景的应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概念

    在Redis数据库中,Bitmap(位图)是一种特殊的数据结构,它不是一个独立的数据类型,而是基于String类型实现的。Bitmap主要用于存储大量二进制位(0或1)的数据,这些位可以代表不同的状态或标志。

  这里的二值状态就是指集合元素的取值就只有 0 和 1 两种。例如在签到打卡的场景中,我们只用记录签到(1)或未签到(0),所以它就是非常典型的二值状态。在签到统计时,每个用户一天的签到用 1 个 bit 位就能表示,一个月(假设是 31 天)的签到情况用 31 个 bit 位就可以,而一年的签到也只需要用 365 个 bit 位,根本不用太复杂的集合类型。这个时候,我们就可以选择 Bitmap。

二、存储原理

      Redis的Bitmap实际上是利用String类型的最大容量(512 MB)存储一个连续的二进制序列,其中每个字节的8位可以分别代表8个独立的状态。这意味着你可以用一个Bitmap来跟踪多达数百万甚至数十亿的状态,只要状态总数不超过 2^(8 * (512 MB / 1 byte)),即大约 2^32 个状态(考虑到字符串末尾的结束符,实际可用的偏移量上限是 2^32 - 1)。

三、常见操作

Redis提供了丰富的Bitmap操作命令,包括但不限于:

SETBIT key offset value:设置指定偏移量处的位状态。
GETBIT key offset:获取指定偏移量处的位状态。
BITCOUNT key [start end]:统计给定范围内为1的位的数量。
BITOP operation destkey key [key ...]:执行针对多个Bitmap的并集、交集、差集等位操作。

SETBIT 

SETBIT key offset value

对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。

位的设置或清除取决于 value 参数,可以是 0 也可以是 1 。

当 key 不存在时,自动生成一个新的字符串值。

字符串会进行伸展(grown)以确保它可以将 value 保存在指定的偏移量上。当字符串值进行伸展时,空白位置以 0 填充。

offset 参数必须大于或等于 0 ,小于 2^32 (bit 映射被限制在 512 MB 之内)。

 

GETBIT 

GETBIT key offset

对 key 所储存的字符串值,获取指定偏移量上的位(bit)。

当 offset 比字符串值的长度大,或者 key 不存在时,返回 0 。

 

 BITCOUNT

BITCOUNT key [start] [end]

计算给定字符串中,被设置为 1 的比特位的数量。

一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。

start 和 end 参数的设置和 GETRANGE 命令类似,都可以使用负数值:比如 -1 表示最后一个位,而 -2 表示倒数第二个位,以此类推。

不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0 。

 

 

BITOP (返回值是以字节为单位,包含8位,这8位中只要有一个有1便返回1,例:偏移量 3是1 9是1 返回2    偏移量1是1 3是1 都在8位内返回1)

BITOP operation destkey key [key ...]

 

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 作为输入。

参考:

And  与   全1出1 
Or     或   有1出1
Not   非   有1出0 有0出1
Xor   异或 相同为0,不同为1 

 

 

 四、优点

      这种数据结构的优点在于它的内存效率极高,特别适合存储需要频繁进行位运算且总体状态较多的情况。同时,Bitmap也可以与其他Redis数据结构结合,实现复杂的数据查询和处理逻辑。

五、举例

1、第一问

 

2、问

清空数据库

(1)求三天一共来了多少人

 先根据数据建模拟表

 三天一共来了多少人

(2)三天每天都来的人数,活跃用户

### Redis Bitmap 的适用场景及应用实例 #### 一、高效的空间利用率和快速操作 Redis Bitmap 提供了一种非常紧凑的方式来存储二进制数据,即每一位可以表示两种状态(0 或 1)。这种特性使得它非常适合用于记录大量布尔类型的标志位信息,在节省内存方面表现出色。由于其底层基于字符串实现,因此能够支持高效的按位运算以及随机访问单个比特位的操作[^1]。 #### 二、用户行为追踪 通过设置特定的时间戳作为键名,并利用用户的唯一标识符映射到位图中的位置来标记某天内该用户是否有过某种活动。例如,对于广告点击情况跟踪而言,每当有用户点击了某个广告时就更新对应的日期下该用户的ID所对应的位置为1;反之则保持默认值0不变。这样就可以轻松统计出一段时间范围内有多少不同的人群参与到了这项活动中去[^3]。 ```python import redis r = redis.Redis() def track_user_action(user_id, date): r.setbit(f"user:action:{date}", user_id, 1) track_user_action(12345, '2023-10-01') ``` #### 三、签到打卡系统 同样地,也可以用来构建简单的考勤管理系统。这里假设每天都有固定的上班时间窗口,则只需要将员工编号转换成整数形式并以此作为索引来设定当天的状态即可完成一次有效的上下班登记动作。之后还可以方便地计算连续工作日长度或是查看某个月份里哪些日子有人缺勤等问题。 ```python def record_attendance(employee_id, workday): r.setbit(f"attendance:{workday}", employee_id, 1) record_attendance(98765, '2023-10-02') ``` #### 四、其他可能的应用方向 除了上述提到的例子之外,还有许多潜在领域值得探索。比如网站流量分析中区分新老访客身份、邮件订阅服务确认收件人是否已读取最新一期通讯等等。只要涉及到频繁发生的事件且每次只关心是否存在而不需要额外携带更多信息的情况下都可能是不错的选择[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值