《闲扯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 ...
随机推荐
- xpath实战
# 1.爬取58二手房信息import requests from lxml import etree #需求:爬取58二手房中的房源信息 if __name__ == '__main__': #爬取 ...
- 每天一个LINUX命令(pwd)
每天一个LINUX命令(pwd) 基本信息 pwd: /bin/pwd,显示当前路径的绝对路径 语法:pwd 应用程序位置 which pwd PWD作用 pwd --help ...
- 从浏览器地址栏输入url到显示页面的步骤(以HTTP为例)
在浏览器地址栏输入URL 浏览器查看缓存,如果请求资源在缓存中并且新鲜,跳转到转码步骤 如果资源未缓存,发起新请求 如果已缓存,检验是否足够新鲜,足够新鲜直接提供给客户端,否则与服务器进行验证. 检验 ...
- 用Python语言绘制股市OBV指标效果
我的新书<基于股票大数据分析的Python入门实战>于近日上架,在这篇博文向大家介绍我的新书:<基于股票大数据分析的Python入门实战>里,介绍了这本书的内容.这里将摘录出部 ...
- abp一代数据迁解析
abp版本5.9 概述 数据迁移无非就是两件事情,1.创建数据库,并根据实体创建对应的表:2.添加一些初始数据 abp的数据迁移也是完成这两件事,比较特殊的是它是多租户saas系统,而且支持不同的租户 ...
- 基于SpringBoot AOP面向切面编程实现Redis分布式锁
基于SpringBoot AOP面向切面编程实现Redis分布式锁 基于SpringBoot AOP面向切面编程实现Redis分布式锁 基于SpringBoot AOP面向切面编程实现Redis分布式 ...
- day68 form组件
目录 一.自定义分页器的拷贝和使用 二.Forms组件 1 前戏 2 form组件的基本功能 3 基本使用 4 基本方法 5 渲染标签 6 展示提示信息 7 钩子函数(HOOK) 8 forms组件其 ...
- day60 django入门
目录 一.静态文件配置 1 引子 2 如何配置 1 在settins.py中的具体配置 2 静态文件的动态解析(html页面中) 二.request对象方法初识 三.pycharm链接数据库(mysq ...
- 利用docker部署elk交换机日志分析
今天我们来聊一下利用docker部署elk日志分析系统,这里解析一下elk是啥东西.elk分别是Elasticsearch,Logstash和Kibana的首字母缩写. Elasticsearch是一 ...
- MYSQL 之 JDBC(十六): DBUtils
DBUtils是Apache组织提供的一个开源的JDBC工具类库,能极大简化jdbc编码的工作量 API介绍 QueryRunner ResultSetHandler 工具类DbUtils 用DBUt ...