【Redis基础和应用】(三)bitmap

Redis位图是一种节省空间的存储bool型数据的方法,常用于记录用户签到等场景。位图可通过getbit/setbit进行位的读写,并能自动扩展。bitcount用于统计1的个数,bitpos查找指定范围内的0或1。Redis 3.2后的bitfield指令允许更灵活的批量位操作,包括get、set和incrby,同时支持溢出策略设置。位字段操作可以高效地进行位段读写和自增操作,适用于多种场景。
摘要由CSDN通过智能技术生成

Redis位图

1. 前言

在平常的开发中,或有一些bool型数据需要存储,比如用户一年的签到记录,签了就记录为1,没签就记录为0,若要记录365天,只需要365bit(46Byte)个空间就可以实现。
在这里插入图片描述
位图不是特殊的数据结构,它的内容其实就是普通的字符串,也就是byte数组。可以使用get/set直接获取和设置整个位图的内容,也可以使用getbit/setbit将byte数组看成位数组来处理。

> setbit <key> <index> <value> # 设置第index位为value
> setbit s 2 1

在这里插入图片描述
注意,Redis的位图,较低位在左,较高位在右边。

2.基本用法

Redis的位数组是自动扩展的,如果设置的某个偏移量超出了现有的内容范围,Redis就会自动将位数组进行零扩充。

如果对应位字节是不可打印字符,redis-cli会显示该字符的十六进制形式。

统计和查找

Redis提供了位图统计指令bitcount和位图查找指令bitpos.

bitcount 用来统计指定位置范围内的1的个数

bitpos 用来查找指定范围内出现的第一个0或者1

例如,可以通过bitcount来查找用户一共签到了多少天, 用bitpos来查找用户从哪一天开始第一次签到的。如果指定了范围[start, end],就可以统计在某个时间范围内用户签到了多少天,用户第一次签到的时间。

但是需要注意的是,start和end参数是字节(Byte)索引,所以指定的位范围必须是8的倍数。

> set w hello
OK
> bitcount w
(integer) 21
> bitcount w 0 0 # 第0个字符中1的个数
(integer) 3
# bitpos <0 | 1> [<start> <end>]
> bitpos 1 0 # 第0个字符起,第一个1的位
(integer) 1
> bitpos 1 1 1
(integer) 9

3. bitfield

前文中的setbitgetbit指定位的值都是单个位的,如果一次要操作多个位,就必须用管道来处理。Redis3.2版本以后新增了一个功能强大的指令bitfield,有这个指令后,不用管道也可以一次进行多个位操作。
在这里插入图片描述

  • bitfield有三个子指令,分别是get,set,incrby,他们都可以对指定位片段进行读写,但是最多只能处理64个连续的位。如果超过64位。
> set w hello
OK
> bitfield w get u4 0 # 从0号位开始获取4个bit, 结果用无符号整数显示 (u)
6
> bitfield w get i3 2 # 从2号位开始,获取3个bit, 结果用有符号整数显示(i)
-3

注意,有符号数最多可以获取64位,无符号最多可以只能获取63位,因为Redis协议中的Integer是有符号数,最大64位,不能传递64位无符号值。如果超出位数限制,Redis就会报参数错误。

  • bitfield可以一次执行多个指令。
> bitfield w get u4 0 get u3 2 get i4 0 get i3 2
1) (integer) 6
2) (integer) 5
3) (integer) 6
4) (integer) -3
  • 使用set指令将第二个字符e改成a, a的ASCII码为97
>bitfield w set u8 8 97 # 从8号位开始,将接下来的8个bit用无符号97的二进制替换。
1) (integer) 101
> get w
"hallo"
  • incrby用来对指定范围的位进行自增操作,既然存在自增,就会出现溢出的问题。若自增出现溢出问题,Redis默认将溢出的符号位丢掉,如果是有符号数127,则加1后溢出编程-128;如果是无符号数255,则加1后溢出变为0。
> set w hello
OK
>bitfield w incrby u4 2 1 # 从2号位开始,对后面的4个bit位进行加1的操作
(integer) 11 # 返回修改后的位 11 = (1011)b

bitfield指令提供了溢出策略子指令overflow,用户可以选择溢出行为,默认是wrap(隐藏),其他行为包括fail(报错不执行),sat(饱和截断,超过范围就停留在最大值或者最小值)。

overflow指令只是影响接下来的第一条指令,这条指令执行完后,溢出策略还是会变为默认值wrap.

> bitfield w overflow fail incrby u4 2 1 # 设置溢出策略为fail
> bitfield w overflow sat incrby u4 2 1 # 设置溢出策略为sat
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

企鹅宝儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值