《闲扯Redis九》Redis五种数据类型之Set型
一、前言
Redis 提供了5种数据类型:String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要。
Redis 中的 Set 是我们经常使用到的一种数据类型,根据使用方式的不同,可以应用到很多场景中。
二、底层实现
集合对象的编码可以是 intset 或者 hashtable 。
intset 编码的集合对象使用整数集合作为底层实现, 集合对象包含的所有元素都被保存在整数集合里面。
举个例子, 以下代码将创建一个如图 8-12 所示的 intset 编码集合对象:
redis> SADD numbers 1 3 5
(integer) 3
结构图 8-12:
另一方面, hashtable 编码的集合对象使用字典作为底层实现, 字典的每个键都是一个字符串对象, 每个字符串对象包含了一个集合元素, 而字典的值则全部被设置为 NULL 。
举个例子, 以下代码将创建一个如图 8-13 所示的 hashtable 编码集合对象:
redis> SADD fruits "apple" "banana" "cherry"
(integer) 3
结构图 8-13:
三、编码转换
当集合对象可以同时满足以下两个条件时, 对象使用 intset 编码:
1.集合对象保存的所有元素都是整数值;
2.集合对象保存的元素数量不超过 512 个;
不能满足这两个条件的集合对象需要使用 hashtable 编码。
注意 : 第二个条件的上限值是可以修改的, 具体请看配置文件中关于 set-max-intset-entries 选项的说明。对于使用 intset 编码的集合对象来说, 当使用 intset 编码所需的两个条件的任意一个不能被满足时, 对象的编码转换操作就会被执行: 原本保存在整数集合中的所有元素都会被转移并保存到字典里面, 并且对象的编码也会从 intset 变为 hashtable。
举个例子, 以下代码创建了一个只包含整数元素的集合对象, 该对象的编码为 intset :
redis> SADD numbers 1 3 5
(integer) 3
redis> OBJECT ENCODING numbers
"intset"
不过, 只要我们向这个只包含整数元素的集合对象添加一个字符串元素,集合对象的编码转移操作就会被执行
redis> SADD numbers "seven"
(integer) 1
redis> OBJECT ENCODING numbers
"hashtable"
除此之外, 如果我们创建一个包含 512 个整数元素的集合对象, 那么对象的编码应该会是 intset :
redis> EVAL "for i=1, 512 do redis.call('SADD', KEYS[1], i) end" 1 integers
(nil)
redis> SCARD integers
(integer) 512
redis> OBJECT ENCODING integers
"intset"
但是, 只要我们再向集合添加一个新的整数元素, 使得这个集合的元素数量变成 513 , 那么对象的编码转换操作就会被执行:
redis> SADD integers 10086
(integer) 1
redis> SCARD integers
(integer) 513
redis> OBJECT ENCODING integers
"hashtable"
四、命令实现
因为集合键的值为集合对象, 所以用于集合键的所有命令都是针对集合对象来构建的, 以下表格列出了其中一部分集合键命令, 以及这些命令在不同编码的集合对象下的实现方法。
命令 | intset 编码的实现方法 | hashtable 编码的实现方法 |
---|---|---|
SADD | 调用 intsetAdd 函数, 将所有新元素添加到整数集合里面。 | 调用 dictAdd , 以新元素为键, NULL 为值, 将键值对添加到字典里面。 |
SCARD | 调用 intsetLen 函数, 返回整数集合所包含的元素数量, 这个数量就是集合对象所包含的元素数量。 | 调用 dictSize 函数, 返回字典所包含的键值对数量, 这个数量就是集合对象所包含的元素数量。 |
SISMEMBER | 调用 intsetFind 函数, 在整数集合中查找给定的元素, 如果找到了说明元素存在于集合, 没找到则说明元素不存在于集合。 | 调用 dictFind 函数, 在字典的键中查找给定的元素, 如果找到了说明元素存在于集合, 没找到则说明元素不存在于集合。 |
SMEMBERS | 遍历整个整数集合, 使用 intsetGet 函数返回集合元素。 | 遍历整个字典, 使用 dictGetKey 函数返回字典的键作为集合元素。 |
SRANDMEMBER | 调用 intsetRandom 函数, 从整数集合中随机返回一个元素。 | 调用 dictGetRandomKey 函数, 从字典中随机返回一个字典键。 |
SPOP | 调用 intsetRandom 函数, 从整数集合中随机取出一个元素, 在将这个随机元素返回给客户端之后, 调用 intsetRemove 函数, 将随机元素从整数集合中删除掉。 | 调用 dictGetRandomKey 函数, 从字典中随机取出一个字典键, 在将这个随机字典键的值返回给客户端之后, 调用dictDelete 函数, 从字典中删除随机字典键所对应的键值对。 |
SREM | 调用 intsetRemove 函数, 从整数集合中删除所有给定的元素。 | 调用 dictDelete 函数, 从字典中删除所有键为给定元素的键值对。 |
五、应用场景
1.抽奖
抽奖
1)用户参与抽奖:SADD order 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
2)查看所有参与抽奖的人:SMEMBERS order
3)重复抽奖每次抽取两人:SMEMBERS order 2
4)不重复抽奖,三等奖3人,二等奖2人,一等奖1人
SPOP order 3
SPOP order 2
SPOP order 1
2.点赞、收藏、标签
点赞、收藏、标签
1)点赞的人:SADD like:1 1001 1002 1003 1004 1005
2)取消点赞:SREM like:1 1002
3)检查用户是否点赞过:
SISMEMBER like:1 1002
SISMEMBER like:1 1005
4)获取点赞人员列表:SMEMBERS like:1
5)获取点赞总人数:SCARD like:1
3.关注模型
redis> SADD wangwu zhangsan lisi zhaoliu haoba
(integer) 4
redis> SADD zhangsan lisi wangwu sijiu
(integer) 3
redis> SADD lisi zhaoliu zhangsan qinshi
(integer) 3
redis> SINTER wangwu zhangsan
1) "lisi"
redis> SISMEMBER zhangsan lisi
(integer) 1
redis> SISMEMBER lisi zhangsan
(integer) 1
redis> SISMEMBER zhaoliu zhangsan
(integer) 0
redis> SISMEMBER haoba zhangsan
(integer) 0
redis> SDIFF zhangsan wangwu
1) "sijiu"
2) "wangwu"
redis> SDIFF lisi wangwu
1) "qinshi"
六、要点总结
(1)集合对象的编码可以是 intset 或者 hashtable 。
(2)intset 编码的集合对象使用整数集合作为底层实现。
(3)hashtable 编码的集合对象使用字典作为底层实现。
(4)intset 与 hashtable 编码之间,符合条件的情况下,可以转换。
over
《闲扯Redis九》Redis五种数据类型之Set型的更多相关文章
- 《闲扯Redis一》五种数据类型之String型
一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...
- Redis支持的五种数据类型
redis支持的五种数据类型: 1.string(字符串) 2.hash(哈希) Redis hash 是一个键值(key=>value)对集合. Redis hash是一个string类型的f ...
- 【Redis】一、Redis简介及五种数据类型
(一)Redis简介 Redis(Remote Dictionary Server)是一个使用ANSI C语言编写.遵守BSD协议.支持网络.可基于内存亦可持久化的日志型.Key-Value的开源 ...
- 《闲扯Redis三》Redis五种数据类型之List型
一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...
- 《闲扯Redis六》Redis五种数据类型之Hash型
一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...
- Redis安装及五种数据类型
redis是非关系型数据库,也叫内存数据库.数据是键值对的形式,通过key查找value 安装Radis:6379 sudo apt-get update sudo apt-get install r ...
- Redis学习笔记--五种数据类型的使用场景
String 1.String 常用命令: 除了get.set.incr.decr mget等操作外,Redis还提供了下面一些操作: 获取字符串长度 往字符串append内容 设置和获取字符串的某一 ...
- <Redis> 入门二 五种数据类型的操作、通用key的操作、发布订阅
文档参考:http://www.redis.net.cn/ string - > key value 简单的keyvalue,常规计数:例如微博数,粉丝数 set -> key v ...
- redis五种数据类型的使用(zz)
redis五种数据类型的使用 redis五种数据类型的使用 (摘自:http://tech.it168.com/a2011/0818/1234/000001234478_all.shtml ) 1.S ...
随机推荐
- 优雅关闭服务下线(Jetty)
在很多时候 kill -9 pid并不是很友好的方法,那样会将我们正在执行请求给断掉,同时eureka 中服务依旧是处于在线状态,这个时候我们可以使用官方提供的actuator来做优雅的关闭处理 - ...
- 「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数
「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数 题面描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数, ...
- 2020年Java基础高频面试题汇总(1.4W字详细解析,你能遇到的都在这了)
1. Java语言有哪些特点 (1)简单易学.有丰富的类库 (2)面向对象(Java最重要的特性,让程序耦合度更低,内聚性更高) (3)与平台无关性(JVM是Java跨平台使用的根本) (4)可靠安全 ...
- 利用docker部署oxidized网络设备备份系统
随着网络设备的增多,通过人手备份网络设备倍感压力,而且效率低.有编程基础的人可能会通过Python的parimiko 或者netmiko 连接到设备操作 把文件通过ftp 上传到FTP服务器, 在通过 ...
- scrapy shell 的使用
是什么?:是一个终端下的调试工具,用来调试scrapy 安装ipython :pip install ipython 启动: scrapy shell + 需要请求的url 进来之后,response ...
- scala 数据结构(九):-filter、化简
1 filter filter:将符合要求的数据(筛选)放置到新的集合中 应用案例:将 val names = List("Alice", "Bob", &qu ...
- 数据可视化之powerBI基础(二十)Power BI度量值和新建表,有什么异同?
https://zhuanlan.zhihu.com/p/101812525 PowerBI中,有三个地方可以使用DAX,分别是度量值.新建列和新建表,这三个功能并成一排摆放在这里,如图所示, 之前 ...
- CMDB02/ 单例模式、资产采集参考命令、日志处理
CMDB02/单例模式.资产采集参考命令.日志处理 目录 CMDB02/单例模式.资产采集参考命令.日志处理 1. 单例模式 1.1 多例模式 1.2 单例模式 1.2.1 单例模式/错误 1.2.2 ...
- Django框架12 /同源、跨域、CORS
Django框架12 /同源.跨域.CORS 目录 Django框架12 /同源.跨域.CORS 1. 同源策略 2. 跨域 3. 解决跨域:CORS/跨域资源共享 1. 同源策略 同源策略(Same ...
- Django框架06 /orm多表操作
Django框架06 /orm多表操作 目录 Django框架06 /orm多表操作 1. admin相关操作 2. 创建模型 3. 增加 4. 删除 5. 修改 6. 基于对象的跨表查询 7. 基于 ...