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

第七章:进入Redis的SET核心

一.SET概念

集合类型也是保存多个字符串类型的元素的,但和列表类型不同的是,集合中1)元素之间是无序的2)元素不可重复。一个集合中最多可以存储无数个元素。Redis除了支持集合内的增删查改操作,同时还支持多个集合取交集、并集、差集,合理地使用好集合类型,能在实际开发中解决很多问题。 

  • 谈到一个术语,这个术语很可能有多种含义。
  • Set:
    1. 集合。
    2. 设置(和 get 相对应)。
  • 集合就是把一些有关联的数据放到一起。
    1. 集合中的元素是无序的!
    2. 集合中的元素是不能重复的(唯一的)。
  • 此处说的无序和前面 list 这里的有序是对应的。
    • 有序:顺序很重要。变换一下顺序,就是不同的 list 了。
    • 无序:顺序不重要。变化一下顺序,集合还是那个集合。
    • 示例:
      • list:[1, 2, 3] 和 [2, 1, 3] 是两个不同的 list。
      • set:[1, 2, 3] 和 [2, 1, 3] 是同一个集合。
  • 和 list 类似,集合中的每个元素也都是 string 类型。(可以使用 json 这样的格式让 string 也能存储结构化数据)。

二.SET核心命令

SADD 命令:将⼀个或者多个元素添加到 set 中。注意,重复的元素⽆法添加到 set 中。
SADD key member [member ...]
时间复杂度:O(1)
返回值:本次添加成功的元素个数

2.1SADD


2.2SMEMBERS 

SMEMBERS命令:获取⼀个 set 中的所有元素,注意,元素间的顺序是无序的。  

SMEMBERS key
时间复杂度:O(N)
返回值:所有元素的列表


2.3SISMEMBER 

SISMEMBER命令:判断⼀个元素在不在 set 中。
SISMEMBER key member
时间复杂度:O(1)
返回值:1 表⽰元素在 set 中。0 表⽰元素不在 set 中或者 key 不存在


2.4SPOP 

SPOP 命令:从 set 中删除并返回⼀个或者多个元素。
  • spop 删除元素的时候其实是随机删除。
  • 不写 count 的时候,随机删除一个;写 count 的时候,就写几个就删几个。
  • 该操作类似于 SRANDMEMBERSRANDMEMBER 从集合中返回一个或多个随机元素但不删除它。
  • 其实是在源码中,针对 spop 实现的时候采取了 “生成随机数” 的方式。

SPOP key [count]
时间复杂度:O(N), n 是 count
返回值:取出的元素。

存储元素是无序的,删除随机删 

 


2.5SMOVE  

SMOVE 命令:将⼀个元素从源 set 取出并放⼊目标 set 中。
  • 把 member 从 source 上删除,再插入到 destination 中。

再次操作时,smove 不会视为出错,也会按照删除 - 插入进行执行。

如果要移动的元素在 source 中不存在,返回 (integer) 0 表示移动失败了。

SMOVE source destination member
时间复杂度:O(1)
返回值:1 表示移动成功,0 表示失败


2.6 SREM 

SREM 命令:将指定的元素从 set 中删除。

可以一次删除一个 member,也可以一次删除多个 member。

SREM key member [member ...]
时间复杂度:O(N), N 是要删除的元素个数.
返回值:本次操作删除的元素个数


  2.7SCARD

SCARD 命令:获取⼀个 set 的基数(cardinality),即 set 中的元素个数。
SCARD key
时间复杂度:O(1)
返回值:set 内的元素个数。


2.8 SRANDMEMBER 

 SRANDMEMBER命令:随机返回集合中的某个元素


相关概念: 

 1.交集(inter):最终结果同时出现在两个集合中。
示例:A 为 {1, 2, 3, 4},B 为 {3, 4, 5, 6},A 和 B 的交集为 {3, 4}。


2.并集(union):把多个集合中的数据都集中放在一起,如果元素有重复,也最终只保留一份。
示例:A 为 {1, 2, 3, 4},B 为 {3, 4, 5, 6},A 和 B 的并集为 {1, 2, 3, 4, 5, 6}。


3.差集(diff):A 和 B 做差集,就是找出哪些元素在 A 中存在,同时在 B 中不存在。
示例:A 为 {1, 2, 3, 4},B 为 {3, 4, 5, 6},A 和 B 做差集为 {1, 2},B 和 A 的差集为 {5, 6}。

2.9SINTER ,SINTERSTSTORE

SINTER命令:获取给定 set 的交集中的元素。
 SINTER key [key ...]
时间复杂度:O(N * M), N 是最⼩的集合元素个数. M 是最大的集合元素个数.
返回值:交集的元素。

SINTERSTORE命令:获取给定 set 的交集中的元素并保存到⽬标 set 中。
SINTERSTORE destination key [key ...]
时间复杂度:O(N * M), N 是最小的集合元素个数. M 是最大的集合元素个数.
返回值:交集的元素个数


2.10SUNION, SUNIONSTORE

SUNION命令:获取给定 set 的并集中的元素。
 SUNION key [key ...]
时间复杂度:O(N), N 给定的所有集合的总的元素个数.
返回值:并集的元素

SUNIONSTORE命令:获取给定 set 的并集中的元素并保存到目标 set 中。
SUNIONSTORE destination key [key ...]
命令有效版本:1.0.0 之后
时间复杂度:O(N), N 给定的所有集合的总的元素个数.
返回值:并集的元素个数。


2.11SDIFF,SDIFFSTORE 

SDIFF命令:获取给定 set 的差集中的元素。
SDIFF key [key ...]
时间复杂度:O(N), N 给定的所有集合的总的元素个数.
返回值:差集的元素。

 

SDIFFSTORE 命令:获取给定 set 的差集中的元素并保存到⽬标 set 中。
SDIFFSTORE destination key [key ...]
时间复杂度:O(N), N 给定的所有集合的总的元素个数.
返回值:差集的元素个数


三.SET内部编码

  • intset(整数集合):当集合中的元素都是整数并且元素的个数小于 set-max-intset-entries 配置(默认 512 个)时,Redis 会选用 intset 来作为集合的内部实现,从而减少内存的使用。
  • hashtable(哈希表):当集合类型无法满足 intset 的条件时,Redis 会使用 hashtable 作为集合的内部实现。

1.当元素个数较少并且都为整数时,内部编码为 intset: 

127.0.0.1:6379> sadd setkey 1 2 3 4
(integer) 4
127.0.0.1:6379> object encoding setkey
"intset"

 2.当元素个数超过 512 个,内部编码为 hashtable

127.0.0.1:6379> sadd setkey 1 2 3 4
(integer) 513
127.0.0.1:6379> object encoding setkey
"hashtable"

 3.当存在元素不是整数时,内部编码为 hashtable

127.0.0.1:6379> sadd setkey a
(integer) 1
127.0.0.1:6379> object encoding setkey
"hashtable"


四.SET的应用场景

 集合类型比较典型的使用场景是标签(tag)。例如 A 用户对娱乐、体育板块比较感兴趣,B 用户对历史、新闻比较感兴趣,这些兴趣点可以被抽象为标签。有了这些数据就可以得到喜欢同一个标签的人,以及用户的共同喜好的标签,这些数据对于增强用户体验和用户黏度都非常有帮助。 例如一个电子商务网站会对不同标签的用户做不同的产品推荐。

  1. 使用 Set 来保存用户的 “标签”(用户画像)
    • 分析出个人的一些特征,分析清楚特征之后,再投其所好,实现 “千人千面”,例如可以分析出性别、年龄、居住地、爱好等特征。
    • 可以根据用户的一些历史行为得出相关特征。
    • 比如对于两个程序、两个账号,判断是否为同一个人,现在的程序登录主要是通过手机号和微信等入口来判断。
    • 通过上述过程搜集到的用户特征,会转换成 “标签”,标签是简短的字符串,此时就可以把标签保存到 redis 的 set 中了。
  2. 使用 Set 来计算用户之间的共同好友
    • 基于 “集合求交集” 操作。
    • 例如在 QQ 中,我加了很多好友,你也加了很多好友,基于此还可以做一些好友推荐。
    • 如 A 和 B 是好友,A 和 C 是好友,B 和 C、D 都是好友,系统就会把 D 推荐给 A。
  3. 使用 Set 统计 UV(去重)
    • 一个互联网产品,衡量用户量、用户规模主要有两方面指标:
      • PV(page view):用户每次访问该服务器,每次访问都会产生一个 pv。
      • UV(user view):每个用户访问服务器,都会产生一个 uv,但同一个用户多次访问,不会使 uv 增加,uv 需要按照用户进行去重,上述的去重过程,可以使用 set 来实现。
  4. Set 方便计算交集
    • 很容易找到两个用户之间的公共标签。
    • 基于这样的标签,衍生出一些 “用户关系”。

http://www.lryc.cn/news/604510.html

相关文章:

  • Java stream 并发问题
  • Redis:缓存雪崩、穿透、击穿的技术解析和实战方案
  • 矩阵指数函数 e^A
  • 如何利用 Redis 的原子操作(INCR, DECR)实现分布式计数器?
  • 微算法科技MLGO突破性的监督量子分类器:纠缠辅助训练算法为量子机器学习开辟新天地
  • 代码随想录算法训练营第五十五天|图论part5
  • Python设计模式详解:策略模式(Strategy Pattern)实战指南
  • OpenBayes 教程上新丨仅激活 3B 参数可媲美 GPT-4o,Qwen3 深夜更新,一手实测来了!
  • 代码随想录day50图论1
  • Apache Ignite 与 Spring Boot 集成
  • 学习游戏制作记录(冻结敌人时间与黑洞技能)7.30
  • nginx安装配置Lua模块的支持
  • 我的世界模组开发教程——资源(1)
  • 【AI】入门级提示词模板:适用于ChatGPT、文心一言等主流模型
  • 【ee类保研面试】数学类---线性代数
  • 从0开始学习R语言--Day62--RE插补
  • JVM对象创建与内存分配机制深度剖析
  • 基于Catboost的铁路交通数据分析及列车延误预测系统的设计与实现【全国城市可选、欠采样技术】
  • 【JVM篇11】:分代回收与GC回收范围的分类详解
  • 数据分析师进阶——95页零售相关数据分析【附全文阅读】
  • JVM 性能调优实战:让系统性能 “飞” 起来的核心策略
  • 观远 ChatBI 完成 DeepSeek-R1 大模型适配:开启智能数据分析跃升新篇
  • 【Spring】一文了解SpringMVC的核心功能及工作流程,以及核心组件及注解
  • Linux 日志管理与时钟同步详解
  • GIS工程师面试题
  • GitHub 热门项目 PandaWiki:零门槛搭建智能漏洞库,支持 10 + 大模型接入
  • UG NX二次开发(Python)-根据封闭曲线创建拉伸特征
  • Class27GoogLeNet
  • 实用性方案:高效处理图片拼接的正确打开方式
  • sed编程入门