当前位置: 首页 > news >正文

Redis实战 - 08 Redis 的 BitMaps 位图命令

文章目录

      • 1. getbit key offset
      • 2. setbit key offset value
      • 3. bitcount key [start end]
      • 4. bitop and|or|not|xor destkey key [key...]
      • 5. bitpos key bit [start] [end]
      • 6. BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment]

现代计算机用二进制位作为信息的基础单位,1个字节等位8位,例如 big 字符串是由3个字节组成,但实际在计算机存储时将其用二进制表示,big 分别对应的ASCII码分别是98、105、103,对应的二进制分别是01100010、01101001和01100111,如下图:

在这里插入图片描述

Bitmaps本身不是一种数据类型, 实际上它就是字符串,但是它可以对字符串的位进行操作。可以把 Bitmaps 想象成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在 Bitmaps 中叫做偏移量。

在这里插入图片描述

合理地使用位能够有效地提高内存使用率和开发效率,很适合用于签到这类场景。比如按月进行存储,一个月最多31天,那么我们将该月用户的签到缓存二进制就是 00000000000000000000000000000000,当某天签到将0改成1即可,而且 Redis 提供 对bitmap 的很多操作比如存储、获取、统计等指令,使用起来非常方便。

1. getbit key offset

在这里插入图片描述

获取位图指定索引的值:

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> set hello big
OK
127.0.0.1:6379> getbit hello 0
(integer) 0
127.0.0.1:6379> getbit hello 15
(integer) 1
127.0.0.1:6379> getbit hello 10
(integer) 1
127.0.0.1:6379> 

2. setbit key offset value

在这里插入图片描述

给位图指定索引设置值,返回该索引位置的原始值:

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> set hello big
OK
127.0.0.1:6379> getbit hello 7
(integer) 0
127.0.0.1:6379> setbit hello 7 1
(integer) 0
127.0.0.1:6379> getbit hello 7
(integer) 1
127.0.0.1:6379> get hello
"cig"
127.0.0.1:6379>

3. bitcount key [start end]

获取位图指定范围(start到end,单位为字节,如果不指定就是获取全部)位值为1的个数:

在这里插入图片描述

默认情况下整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。start、end 是指 bit 组的字节的下标数,二者皆包含。

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> set hello big
OK
127.0.0.1:6379> bitcount hello
(integer) 12
127.0.0.1:6379> getbit hello 7
(integer) 0
127.0.0.1:6379> setbit hello 7 1
(integer) 0
127.0.0.1:6379> bitcount hello 
(integer) 13
127.0.0.1:6379> bitcount hello 0 1
(integer) 8
127.0.0.1:6379> bitcount hello 0 2
(integer) 13
127.0.0.1:6379> bitcount hello 1 1
(integer) 4
127.0.0.1:6379> bitcount hello 1 2
(integer) 9
127.0.0.1:6379> bitcount hello 2 2
(integer) 5
127.0.0.1:6379> 

4. bitop and|or|not|xor destkey key [key…]

做多个bitmap的and(交集)、or(并集)、not(非)、xor(异或)操作并将结果保存到 destkey 中:

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> set hello big
OK
127.0.0.1:6379> set world big
OK
127.0.0.1:6379> bitop and destkey hello world
(integer) 3
127.0.0.1:6379> bitop or destkey hello world
(integer) 3
127.0.0.1:6379> get destkey
"big"
127.0.0.1:6379> bitop not destkey hello
(integer) 3
127.0.0.1:6379> get destkey
"\x9d\x96\x98"
127.0.0.1:6379> bitop xor destkey hello world
(integer) 3
127.0.0.1:6379> get destkey
"\x00\x00\x00"
127.0.0.1:6379>

5. bitpos key bit [start] [end]

返回字符串里面第一个被设置为1或者0的bit位:

在这里插入图片描述

默认情况下整个字符串都会被检索一次,只有在指定start和end参数(指定start和end位是可行的),该范围被解释为一个字节的范围,而不是一系列的位。所以start=0 并且 end=2是指前三个字节范围内查找。

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> set hello big
OK
127.0.0.1:6379> bitpos hello 1
(integer) 1
# 查找字符串里面bit值为0的位置
127.0.0.1:6379> bitpos hello 0
(integer) 0
# 从第1个字节开始的位置,查找字符串里面bit值为0的位置
127.0.0.1:6379> bitpos hello 0 1
(integer) 8
# 第2个字节开始的位置,查找字符串里面bit值为1的位置 
127.0.0.1:6379> bitpos hello 1 2
(integer) 17
# 第0个字节开始到第1个字节结束的位置,查找字符串里面bit值为1的位置
127.0.0.1:6379> bitpos hello 1 0 1
(integer) 1
127.0.0.1:6379>

6. BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment]

BITFIELD 命令可以将一个 Redis 字符串看作是一个由二进制位组成的数组, 并对这个数组中储存的长度不同的整数进行访问 (被储存的整数无需进行对齐)。 换句话说, 通过这个命令, 用户可以执行诸如 “对偏移量 1234 上的 5 位长有符号整数进行设置”、 “获取偏移量 4567 上的 31 位长无符号整数”等操作。 此外, BITFIELD 命令还可以对指定的整数执行加法操作和减法操作, 并且这些操作可以通过设置妥善地处理计算时出现的溢出情况。

BITFIELD 命令可以在一次调用中同时对多个位范围进行操作: 它接受一系列待执行的操作作为参数, 并返回一个数组作为回复, 数组中的每个元素就是对应操作的执行结果。

一次对多个位范围进行操作。bitfield 有三个子指令,分别是 get/set/incrby。每个指令都可以对指定片段做操作。

在这里插入图片描述

子命令:GET —— 返回指定的二进制位范围。

bitfield key get type offset

# 类型u代表无符号十进制,i代表带符号十进制
# 从偏移量offset=0开始取3位,获取无符号整数的值(将前3位二进制011转为无符号10进制返回)
127.0.0.1:6379> bitfield hello get u3 0
1) (integer) 3
# 从偏移量offset=0开始取4位,获取无符号整数的值(将前4位二进制0110转为无符号10进制返回)
127.0.0.1:6379> bitfield hello get u4 0
1) (integer) 6
# 从偏移量offset=0开始取5位,获取无符号整数的值(将前5位二进制01100转为无符号10进制返回)
127.0.0.1:6379> bitfield hello get u5 0
1) (integer) 12
# 从偏移量offset=1开始取2位,获取无符号整数的值(11前面补0,就是0011,转为无符号10进制返回)
127.0.0.1:6379> bitfield hello get u2 1
1) (integer) 3
# 从偏移量offset=0开始取2位,获取带符号整数的值(01前面补0,就是0001,转为带符号10进制返回)
127.0.0.1:6379> bitfield hello get i2 0
1) (integer) 1
127.0.0.1:6379> 

子命令:SET —— 对指定的二进制位范围进行设置,并返回它的旧值。

bitfield key set type offset value

# 从偏移量offset=0开始取3位,设置为无符号的整数5并返回旧值
127.0.0.1:6379> bitfield hello set u3 0 5
1) (integer) 3
127.0.0.1:6379> bitfield hello get u3 0
1) (integer) 5
# 从偏移量offset=0开始取4位,设置为无符号的整数6并返回旧值
127.0.0.1:6379> bitfield hello set u4 0 6
1) (integer) 10
127.0.0.1:6379> bitfield hello get u4 0
1) (integer) 6
# 从偏移量offset=0开始取4位,设置为带符号的整数5并返回旧值
127.0.0.1:6379> bitfield hello set i4 0 5
1) (integer) 6
127.0.0.1:6379> bitfield hello get i4 0
1) (integer) 5

子命令:INCRBY —— 对指定的二进制位范围执行加法操作,并返回它的旧值。用户可以通过向 increment 参数传入负值来实现相应的减法操作。

bitfield key incrby type offset increment

# 从偏移量offset=0开始取4位,获取无符号整数的值
# 从偏移量offset=6开始取4位,设置为无符号的整数6 
# 从偏移量offset=4开始取4位,获取无符号整数的值并自增1
127.0.0.1:6379> bitfield hello get u4 0 set u4 4 6 incrby u4 4 1
1) (integer) 5
2) (integer) 2
3) (integer) 7
# 从偏移量offset=0开始取4位,获取无符号整数的值
127.0.0.1:6379>  bitfield hello get u4 0
1) (integer) 5
# 从偏移量offset=4开始取4位,设置为无符号整数6
127.0.0.1:6379>  bitfield hello set u4 4 6
1) (integer) 7
# 从偏移量offset=4开始取4位,获取无符号整数的值并自增1
127.0.0.1:6379> bitfield hello incrby u4 4 1
1) (integer) 7
# 从偏移量offset=4开始取4位,获取无符号整数的值
127.0.0.1:6379> bitfield hello get u4 4
1) (integer) 7
# 从偏移量offset=4开始取4位,获取无符号整数的值并自增1
127.0.0.1:6379> bitfield hello get u4 4 incrby u4 4 1
1) (integer) 7
2) (integer) 8
# 从偏移量offset=0开始取4位,获取无符号整数的值
127.0.0.1:6379> bitfield hello get u4 4
1) (integer) 8
127.0.0.1:6379>

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 改进YOLOv5系列:首发结合最新CSPNeXt主干结构(适用YOLOv7),高性能,低延时的单阶段目标检测器主干,通过COCO数据集验证高效涨点
  • 基于导频的信道估计实现
  • 小满Vue3第四十五章(Vue3 Web Components)
  • Linux 内核页表管理
  • 基于MAX-SUM算法的大规模信息系统的协调问题matlab仿真
  • 【Spring+SpringMVC+Mybatis】Spring+SpringMVC+Mybatis实现前端到后台完整项目
  • c#,c++,qt中多线程访问UI控件线程的问题汇总
  • 详解预处理指令(#define)
  • JS第五课(JS的分支语句)
  • 【项目实战】自主实现HTTP(七)——错误处理、线程池引入、项目扩展及结项
  • 时序预测 | MATLAB实现贝叶斯优化CNN-LSTM时间序列预测(股票价格预测)
  • 【程序环境与预处理】
  • Vue3 之 Pinia - 状态管理
  • QT creator 新建项目
  • [云原生·k8s] 终于读懂了Kubernetes
  • JavaScript 如何正确处理 Unicode 编码问题!
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • Android交互
  • Android开源项目规范总结
  • C++类的相互关联
  • Java的Interrupt与线程中断
  • java多线程
  • k8s 面向应用开发者的基础命令
  • Python学习笔记 字符串拼接
  • 分布式熔断降级平台aegis
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 译自由幺半群
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • #07【面试问题整理】嵌入式软件工程师
  • #Lua:Lua调用C++生成的DLL库
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (Java)【深基9.例1】选举学生会
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (一)Linux+Windows下安装ffmpeg
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (自用)网络编程
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .NET Core WebAPI中封装Swagger配置
  • .net Stream篇(六)
  • .NET 直连SAP HANA数据库
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • .NET学习全景图
  • @column注解_MyBatis注解开发 -MyBatis(15)
  • @SpringBootApplication 包含的三个注解及其含义
  • [240607] Jina AI 发布多模态嵌入模型 | PHP 曝新漏洞 | TypeScript 5.5 RC 发布公告
  • [Android开源]EasySharedPreferences:优雅的进行SharedPreferences数据存储操作
  • [Arduino学习] ESP8266读取DHT11数字温湿度传感器数据
  • [BUG]Datax写入数据到psql报不能序列化特殊字符
  • [C#]C# winform部署yolov8目标检测的openvino模型
  • [CISCN 2019华东南]Web11
  • [Effective C++读书笔记]0012_复制对象时勿忘其每一部分