什么是位图

位图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. SpringBoot 监控中心

    1,SpringBoot 监控中心: 针对微服务服务监控,服务器内存内存变化(对内存,线程,日志管理),检测服务配置连接地址是否可用(模拟访问,懒加载),故意将mysql 数据源连接密码写错,启动就会 ...

  2. iOS hash

    一.iOS hash 下图列出 Hash 在 iOS 中的应用分析整理 知乎上的一句话: 算法.数据结构.通信协议.文件系统.驱动等,虽然自己不写那些东西,但是了解其原理对于排错.优化自己的代码有很大 ...

  3. iOS UmbrellaFramework

    一.umbrella framework 将几个已经封装好的 framework 封装成一个,封装的这种 framework 就是 umbrella framework. Apple 的官方文档中明确 ...

  4. mongodb的增加和删除

    一  mongodb中使用insert()方法来增加集合中的文档: db.myTable.insert({name:'arvin',age:12}) //对名为myTable的集合插入数据 插入数据 ...

  5. 12.1 flask基础之简单实用

    一.Flask介绍(轻量级的框架,非常快速的就能把程序搭建起来) Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是 ...

  6. ES6 class 类的理解(一)

    优点 ES6 的类提供了几点明显的好处: 兼容当前大量的代码. 相对于构造器和构造器继承,类使初学者更容易入门. 子类化在语言层面支持. 可以子类化内置的构造器. 不再需要继承库:框架之间的代码变得更 ...

  7. HBase 监控 | HBase Metrics 初探(一)

    前言:对于任意一个系统而言,做好监控都是非常重要的,HBase也不例外.经常,我们会从JMX中获取相关指标来做展示.对HBase进行监控,那这些指标是怎么生成的呢?如果你想自定义自己的监控指标又该怎么 ...

  8. Aho-Corasick automaton

    目录 KMP 算法 BF 算法 KMP 算法 避免重复遍历 算法思想 代码实现 匹配函数 求 next 数组 字典树 多模匹配 构造字典树 字典树的结构体定义 构造算法 伪代码 代码实现 失配指针 功 ...

  9. PTA数据结构与算法题目集(中文) 7-28

    PTA数据结构与算法题目集(中文)  7-28 7-28 搜索树判断 (25 分)   对于二叉搜索树,我们规定任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值.如果我 ...

  10. Java反射(六)纯面向接口编程的简单框架实践

    我们知道在使用MyBatis开发时,只需要添加DAO接口和对应的映射XML文件,不需要写DAO的实现类,其实底层是通过动态代理实现. 本文将使用前几篇文章的知识点实现一个纯面向接口编程的简单框架,与M ...