什么是位图

位图bitmap是通过一个bit来表示某个元素对应的值或者状态,是由一组bit位组成,每个bit位对应0和1两个状态,虽然内部还是采用string类型进行存储,但是redis提供了直接操作位图的指令,可以把他看作是一个bit数组,数组的下标就是偏移量。

常用命令介绍

一、SETBIT key offset value

可用版本:>=2.20

时间复杂度:O(1)

作用

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

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

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

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

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

返回值

原来储存的位

示例

# 在key值为bitkey的偏移量0处,设置值为1
redis> setbit bitkey 0 1
# 返回原存储的值
(integer) 0
# 在key值为bitkey的偏移量0处,设置值为1
redis> setbit bitkey 0 0
# 返回原存储的值
(integer) 1

二、GETBIT key offset

可用版本:>=2.2.0

时间复杂度:O(1)

作用

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

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

返回值

字符串值指定偏移量上的位

示例

# 不存在的key
redis>getbit bitkey_0
(integer) 0
reids>setbit bitkey_0 0 0
(integer) 1
# 超过默认的偏移量(没有grown)
redis>getbit bitkey_0 10000
(integer) 0
redis>getbit bitkey_0 0
(integer) 1

三、 BITCOUNT key [start] [end]

可用版本:>=2.6.0

时间复杂度:O(N)

作用

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

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

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

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

示例

redis>setbit key_count 0 1
(integer) 0
redis>setbit key_count 1 1
(integer) 0
redis>setbit key_count 2 0
(integer) 0
redis>bitcount key_count
(integer) 2

四、BITPOS key bit [start] [end]

可用版本:>= 2.8.7

时间复杂度:O(N),其中N为位图包含的二进制位数量

作用

返回位图中第一个值为bit的二进制的位置

在默认情况下,命令将检测整个位图,但用户也可以通过start和end参数来指定要检测的范围

返回值

整数返回

示例

redis>setbit key_pos 2 1
(integer) 0
redis>bitpos key_pos 0
(integer) 0
redis>bitpos key_pos 1
(integer) 2

五、BITOP operation destkey key [key …]

可用版本:>=2.6.0

时间复杂度:O(N)

作用

对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。

operation 可以是 ANDORNOTXOR 这四种操作中的任意一种:

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

返回值

保存到 destkey 的字符串的长度,和输入 key 中最长的字符串长度相等。

示例

# 先保存几组
# key_1:1001 key_2:1011
redis> setbit key_1 0 1
(integer) 0
redis> setbit key_1 3 1
(integer) 0
redis> setbit key_2 0 1
(integer) 0
reids> setbit key_2 2 1
(integer) 0
reids> setbit key_2 3 1
(integer) 0
# AND key求逻辑并
redis> bitop and key_and key_1 key_2 # 结果将是1001
(integer) 1
# OR key求逻辑或
redis> bitop or key_or key_1 key_2 # 1011
(integer) 1
# XOR key求逻辑异或
redis> bitop xor key_xor key_1 key_2 # 0100
(integer) 1
# NOT key求逻辑非
redis> bitop not key_not key_1 # 0110
(integer) 1

六、BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]

可用版本:>= 3.2.0

时间复杂度:每个子命令的复杂度为 O(1)

作用

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

返回值

返回一个数组作为回复, 数组中的每个元素就是对应操作的执行结果。

案例

# 从第1位开始取4位,设值为5(有符号数)
redis> BITFIELD key SET i4 0 5
1) (integer) 0 # 从第1位开始取4位,结果为有符号数
redis> BITFIELD key GET i4 0
1) (integer) 5 # 从第1位取4位,结果为有符号数
# 从第5位取4位,设值为6,结果为无符号数
# 从第5位去4位,值增加1,结果为无符号数
redis> BITFIELD key GET i4 0 SET u4 4 6 INCRBY u4 4 1
1) (integer) 5
2) (integer) 0
3) (integer) 7

BITFIELD还提供了三种溢出策略:

  • WRAP(wrap around,回绕)。一个i8的整数,值为127,递增1会导致值变为-128;
  • SAT(saturation arithmetic,饱和计算)。一个i8的整数,值为120,递增10结果变为127(i8 类型所能储存的最大整数值);
  • FAIL。 发生溢出时,操作失败。并返回空值表示计算未被执行。
redis> BITFIELD tian_key SET i8 0 127 OVERFLOW WRAP INCRBY i8 0 1
1) (integer) 0
2) (integer) -128
redis> BITFIELD tian_key_2 SET i8 0 120 OVERFLOW SAT INCRBY i8 0 10
1) (integer) 0
2) (integer) 127
redis> BITFIELD tian_key_3 SET i8 0 127 OVERFLOW FAIL INCRBY i8 0 1
1) (integer) 0
2) (nil)

Redis学习与应用-位图的更多相关文章

  1. Redis学习笔记之位图

    目录 位图定义 应用场景 基本使用 查找统计 位图定义 位图并不是一种数据结构,其实就是一种普通的字符串,也可以说是byte数组.基本语法是setbit/getbit,刚才说了是一个byte数组,所以 ...

  2. redis 学习(1)-- redis 安装与启动

    redis 学习(1)-- redis 安装与启动 redis 特性 关于 redis 的介绍网上已经有很多信息了,这里我就不在详细说明了.介绍一下几个鲜明特性: 1.速度快 官方称可以达到10W的q ...

  3. Redis学习手册(目录)

    为什么自己当初要选择Redis作为数据存储解决方案中的一员呢?现在能想到的原因主要有三.其一,Redis不仅性能高效,而且完全免费.其二,是基于C/C++开发的服务器,这里应该有一定的感情因素吧.最后 ...

  4. redis 学习笔记(6)-cluster集群搭建

    上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞shardi ...

  5. Redis——学习之路四(初识主从配置)

    首先我们配置一台master服务器,两台slave服务器.master服务器配置就是默认配置 端口为6379,添加就一个密码CeshiPassword,然后启动master服务器. 两台slave服务 ...

  6. Redis——学习之路三(初识redis config配置)

    我们先看看config 默认情况下系统是怎么配置的.在命令行中输入 config get *(如图) 默认情况下有61配置信息,每一个命令占两行,第一行为配置名称信息,第二行为配置的具体信息.     ...

  7. Redis——学习之路二(初识redis服务器命令)

    上一章我们已经知道了如果启动redis服务器,现在我们来学习一下,以及如何用客户端连接服务器.接下来我们来学习一下查看操作服务器的命令. 服务器命令: 1.info——当前redis服务器信息   s ...

  8. Redis学习笔记~目录

    回到占占推荐博客索引 百度百科 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合). ...

  9. Redis学习笔记4-Redis配置详解

    在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redi ...

随机推荐

  1. Go解算法07整数反转

    描述 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123 输出: 321  示例 2: 输入: -123 输出: -321 示例 3: 输入: 120 ...

  2. coding++:thymelef 模板报错 the entity name must immediately follow the '&' in the entity reference

    thymelef模板里面是不能实用&符号的 要用&转义符代替,官网也有文档说明可以用官方的通配符代替, 官方文档 http://www.thymeleaf.org/doc/tutori ...

  3. .Net微服务实践(三):Ocelot配置路由和请求聚合

    目录 配置 路由 基本配置 占位符 万能模板 优先级 查询参数 请求聚合 默认聚合 自定义聚合 最后 在上篇.Net微服务实践(二):Ocelot介绍和快速开始中我们介绍了Ocelot,创建了一个Oc ...

  4. PHP友盟推送消息踩坑及处理

    公司的客户端的推送选用友盟推送,但是友盟的官方文档描述很少,对新手很不友好,所以特写此采坑纪录,废话不多说上代码. 公司业务只涉及单播和广播.所以只提供了单播和广播,业务拓展的话会补充其余部分. 消息 ...

  5. 关于 Vue 中 我对中央事线管理器的(enentBus)误解

    由于这段时间公司比较闲,就对vue 中的一些模糊的点做了一些加强,突然就想到了常挂在嘴边兄弟组件传值 我理解的兄弟组件的传值是可以跨理由传值的,比如我从http://localhost:8080/lo ...

  6. Oracle数据库表和表列讲解

    如果将数据库比作一个存储东西的储物柜,表就像是储物柜上的各个抽屉,每个抽屉分门别类地存放了各种数据,在设计和规划数据库时,表的定义和规划往往相当重要,良好的表设计决定了程序人员编写程序的便利性与数据库 ...

  7. 1023 Have Fun with Numbers (20 分)

    1023 Have Fun with Numbers (20 分)   Notice that the number 123456789 is a 9-digit number consisting ...

  8. KMP算法-从头到尾彻底理解KMP

    一:背景 给定一个主串(以 S 代替)和模式串(以 P 代替),要求找出 P 在 S 中出现的位置,此即串的模式匹配问题. Knuth-Morris-Pratt 算法(简称 KMP)是解决这一问题的常 ...

  9. Python起步学习

    Python起步学习 案例1:程序输入输出 案例2:判断合法用户 安全3:编写判断成绩的程序 1 案例1:程序输入输出 1.1 问题 编写login.py脚本,实现以下目标: 提示用户输入用户名 将用 ...

  10. dotnet CLI工具是如何运行你的代码的

    原文连接:https://mattwarren.org/2016/07/04/How-the-dotnet-CLI-tooling-runs-your-code/作者 Matt Warren.授权翻译 ...