• Redis——》数据类型:bitmap


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


    相关链接:
        Redis——》数据类型
        Redis——》数据类型:string(字符串)
        Redis——》数据类型:hash(哈希)
        Redis——》数据类型:list(列表)
        Redis——》数据类型:set(集合)
        Redis——》数据类型:zset(有序集合)
        Redis——》数据类型:bitmap

    一、底层结构

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

    二、最大长度

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

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

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

    getbit key offset

    getbit k1 0
    getbit k1 3
    getbit k1 5
    getbit k1 7
    getbit k1 111
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    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:1001010010010101
    
    bitop and and_result bitmap1 bitmap2
    bitop or or_result bitmap1 bitmap2
    bitop xor xor_result bitmap1 bitmap2
    bitop not not_result bitmap1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1、记录用户登录状态

    以下属于同一类场景:

    • 记录用户登录状态
    • 记录用户打卡状态
    • 记录用户参与活动状态
    假设用户ID为10086
    
    思路:
    	key		:存储用户登陆状态集合数据,当前为user:login:status
    	offset	:存储用户ID,当前为10086
    	value	:存储登录状态(在线为1,下线为0)
    
    # 记录用户登录
    setbit user:login:status 10086 1
    
    # 记录用户登出
    setbit user:login:status 10086 0
    
    # 判断用户是否登录(在线为1,下线为0)
    getbit user:login:status 10086
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2、统计用户登录天数

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

    假设用户ID为10086
    
    思路:
    	key		:存储用户登陆状态集合数据,当前为user:login:10086
    	offset:存储天数-1
    	value	:存储登录状态(在线为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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    在这里插入图片描述

  • 相关阅读:
    Rocketmq使用手册第一篇(springboot整合rocketmq)
    深拷贝和浅拷贝
    云原生gitlab在k8s上配置ingress ssh端口访问仓库
    【Git】Git提交代码到远程仓库,删除分支,克隆到本地 等操作指令
    欺诈检测中的不平衡分类
    主机访问虚拟机中docker安装的mysql
    初识ElasticSearch
    关于电影的HTML网页设计-威海影视网站首页-电影主题HTM5网页设计作业成品
    SIM8262E-M2,SIM8262A-M2,SIM8260C-M2,SIM8260C 5G定位模组支持多频段
    企业电子招标采购系统源码Spring Boot + Mybatis + Redis + Layui + 前后端分离 构建企业电子招采平台之立项流程图
  • 原文地址:https://blog.csdn.net/weixin_43453386/article/details/128093271