Redis——》数据类型:bitmap
创始人
2024-02-27 18:14:07

推荐链接:
    总结——》【Java】
    总结——》【Mysql】
    总结——》【Redis】
    总结——》【Spring】
    总结——》【SpringBoot】
    总结——》【MyBatis、MyBatis-Plus】

Redis——》数据类型:bitmap

  • 一、底层结构
  • 二、最大长度
  • 三、操作示例
    • 1、setbit:设置二进制位的值
    • 2、getbit:获取二进制位的值
    • 3、bitcount:统计二进制位为1的数量
    • 4、bitops:查找第一个指定的二进制位值
    • 5、bitop:位操作
    • 6、bitfield:在位图中存储整数值
  • 四、使用场景
    • 1、记录用户登录状态
    • 2、统计用户登录天数
    • 3、统计用户每个月的签到情况
    • 4、统计连续签到用户总数

一、底层结构

由多个二进制位组成的数组,数组中的每个二进制位都有与之对应的偏移量(也称索引),用户通过这些偏移量可以对位图中指定的一个或多个二进制位进行操作。

二、最大长度

512Mb = 512 * 1024 * 1024 * 8 = 2^32

三、操作示例

命令帮助语法描述
setbithelp setbitsetbit key offset value设置二进制位的值
getbithelp getbitgetbit key offset获取二进制位的值
bitcounthelp bitcountbitcount key [start end]统计二进制位为1的数量
bitopshelp bitopsbitpos key bit [start] [end]查找第一个指定的二进制位值
bitophelp bitopbitop 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
bitfield在位图中存储整数值

1、setbit:设置二进制位的值

注意:
(1)如果设置某个偏移量超出了现有的内容范围,位数组就会自动扩充。
因为Redis对位图的扩展操作是以字节为单位进行的,所以扩展之后的位图包含的二进制位数量可能会比用户要求多一些,并且在扩展位图的同时,Redis还会将所有未被设置的二进制位的值初始化为0。
(2)setbit命令只能使用正数偏移量,输入负数会报错

setbit key offset value

# 底层的二进制:10000000
setbit k1 0 1# 底层存储的二进制:10010000
setbit k1 3 1# 底层存储的二进制:10010100
setbit k1 5 1# 底层存储的二进制:10010100 01000000
setbit k1 9 1

在这里插入图片描述

2、getbit:获取二进制位的值

注意:
如果输入的偏移量超过了位图目前拥有的最大偏移量,那么getbit命令将返回0

getbit key offset

getbit k1 0
getbit k1 3
getbit k1 5
getbit k1 7
getbit k1 111

在这里插入图片描述

3、bitcount:统计二进制位为1的数量

注意:
(1)默认对所有字节中的二进制位进行统计
(2)start、end对指定字节范围内的二进制位进行统计(正向字节偏移量从0开始,反向从-1开始)

bitcount key [start end]

命令描述
bitcount k1在所有字节中,统计二进制位为1的数量
bitcount k1 0 -1在所有字节中,统计二进制位为1的数量
bitcount k1 0 0在第1个字节中,统计二进制位为1的数量
bitcount k1 1 1在第2个字节中,统计二进制位为1的数量
bitcount k1 -1 -1在最后1个字节中,统计二进制位为1的数量
bitcount k1 -2 -2在倒数第2个字节中,统计二进制位为1的数量
bitcount k1 0 1在前2个字节中,统计二进制位为1的数量
bitcount k1 -2 -1在后2个字节中,统计二进制位为1的数量

在这里插入图片描述

4、bitops:查找第一个指定的二进制位值

注意:
(1)默认对所有字节中查找第一个指定的二进制位值
(2)start、end对指定字节范围内查找第一个指定的二进制位值(正向字节偏移量从0开始,反向从-1开始)
(3)对一个不存在的位图或者一个所有位都被设置成0的位图中查找值为1的二进制位时,BITPOS命令将返回-1

bitpos key bit [start] [end]

命令描述
bitpos k1 0在所有字节中,查找第1个为0的位偏移量
bitpos k1 1在所有字节中,查找第1个为1的位偏移量
bitpos k1 1 0 -1在所有字节中,查找第1个为1的位偏移量
bitpos k1 1 0 0在第1个字节中,查找第1个为1的位偏移量
bitpos k1 1 1 1在第2个字节中,查找第1个为1的位偏移量
bitpos k1 1 -1 -1在最后1个字节中,查找第1个为1的位偏移量
bitpos k1 1 -2 -2在倒数第2个字节中,查找第1个被设置为1的位偏移量
bitpos k1 1 0 1在前2个字节中,查找第1个被设置为1的位偏移量
bitpos k1 1 -2 -1在后2个字节中,查找第1个被设置为1的位偏移量

在这里插入图片描述

5、bitop:位操作

注意:
当BITOP命令在对两个长度不同的位图执行运算时,会将长度较短的那个位图中不存在的二进制位的值看作0。

命令描述
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
# bitmap1:01010011
# bitmap2:1001010010010101bitop and and_result bitmap1 bitmap2
bitop or or_result bitmap1 bitmap2
bitop xor xor_result bitmap1 bitmap2
bitop not not_result bitmap1

在这里插入图片描述

6、bitfield:在位图中存储整数值

四、使用场景

# 设置二进制位的值
setbit key offset value# 获取二进制位的值
getbit key offset# 统计二制位为1的数量
bitcount key [start end]# 查找第一个指定的二进制位值
bitpos key bit [start] [end]# 对一个或多个 key 求逻辑并,并将结果保存到 destkey 
bitop and destkey key [key …]	

1、记录用户登录状态

以下属于同一类场景:

  • 记录用户登录状态
  • 记录用户打卡状态
  • 记录用户参与活动状态
假设用户ID为10086思路:key		:存储用户登陆状态集合数据,当前为user:login:statusoffset	:存储用户ID,当前为10086value	:存储登录状态(在线为1,下线为0)# 记录用户登录
setbit user:login:status 10086 1# 记录用户登出
setbit user:login:status 10086 0# 判断用户是否登录(在线为1,下线为0)
getbit user:login:status 10086

2、统计用户登录天数

一年最多366天 = 366个二进制位 = 45.75个字节 ≈ 46个字节

假设用户ID为10086思路:key		:存储用户登陆状态集合数据,当前为user:login:10086offset:存储天数-1value	:存储登录状态(在线为1,下线为0)# 记录用户第2天登录
setbit user:login:10086 1 1# 记录用户第8天登录
set user:login:10086 7 1# 记录用户第365天登录
set user:login:10086 364 1# 字节长度:46
strlen sean# 统计用户登录天数
bitcount user:login:10086# 统计用户最后2周登录天数,结果:1
bitcount user:login:10086 -2 -1

3、统计用户每个月的签到情况

假设用户ID为10086,当前日期为2022年11月29日思路:key		:存储用户每月每天签到状态集合数据,当前为user:sign:{userId}:{yyyyMM}offset	:存储对应日期-1(因为offset从0开始)value	:存储签到状态(签到为1,未签到为0)# 记录用户2022年11月29日签到
setbit user:sign:10086:202211 28 1# 判断用户2022年11月29日是否签到
getbit user:sign:10086:202211 28# 统计用户2022年11月签到次数
bitcount user:sign:10086:202211# 查找用户2022年11月首次签到日期(因为offset从0开始,所以日期值=offset+1)
bitpos user:sign:10086:202211 1

4、统计连续签到用户总数

假设从2022年11月27日到2022年11月29日,如何统计出这3天连续打卡用户总数?思路:(1)3天对应3个Bitmap,并且offset上的userID都是一样的。(2)3个Bitmap做『并』运算(如果offset上的值都为1,则说明这个用户3天连续打卡)。(3)把『并』结果保存到一个新 Bitmap 中,统计 bit = 1 的个数便得到了连续打卡 3 天的用户总数了。# 记录2022年11月27日用户签到
setbit user:sign:20221127 10086 1
setbit user:sign:20221127 10087 1
setbit user:sign:20221127 10088 1
setbit user:sign:20221127 10089 1# 记录2022年11月28日用户签到
setbit user:sign:20221128 10087 1
setbit user:sign:20221128 10088 1
setbit user:sign:20221128 10089 1# 记录2022年11月29日用户签到
setbit user:sign:20221129 10088 1
setbit user:sign:20221129 10089 1# 与操作
bitop and destkey user:sign:20221127 user:sign:20221128 user:sign:20221129# 统计 bit 位 = 1 的个数
bitcount destkey 1

在这里插入图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...