news 2026/5/12 21:43:28

Redis Set:原理、命令与实战场景详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Redis Set:原理、命令与实战场景详解

Redis 数据结构精讲:Set 集合的原理、命令与实战场景

大家好,今天我们来聊聊 Redis 中一个非常实用的数据结构 ——Set(集合)。它和我们熟悉的列表(List)有很多相似之处,比如都能存储多个字符串类型的元素,但也有几个关键区别:Set 中的元素是无序的,而且不允许重复。更重要的是,Redis 的 Set 天生支持交集、并集、差集这些集合操作,在很多业务场景下都能发挥奇效。


一、Set 集合的基本概念

先看个直观的例子,比如我们要记录用户user:1的兴趣爱好:

可以看到,Set 的 Key 是user:1:subscribe,对应的 Value 是一个包含BasketballITMusic等多个元素的集合。这些元素没有固定顺序,也不会重复,完美契合了 “用户兴趣标签” 这类场景的需求。


二、Set 集合的基础命令详解

我们先从最常用的基础命令开始,逐个拆解它们的用法、时间复杂度和实战示例。

1. SADD:添加元素到集合

作用:将一个或多个元素添加到集合中,重复元素会被自动忽略。

  • 语法SADD key member [member \.\.\.\]

  • 时间复杂度:O(1)

  • 返回值:本次成功添加的元素个数

redis> SADD myset "Hello" (integer) 1 redis> SADD myset "World" (integer) 1 redis> SADD myset "World" (integer) 0 # 重复元素添加失败,返回0 redis> SMEMBERS myset 1) "Hello" 2) "World"

2. SMEMBERS:获取集合中所有元素

作用:返回集合中的所有元素,注意元素的顺序是无序的。

  • 语法SMEMBERS key

  • 时间复杂度:O (N)(N 为集合元素个数)

  • 返回值:集合中所有元素的列表

redis> SADD myset "Hello" (integer) 1 redis> SADD myset "World" (integer) 1 redis> SMEMBERS myset 1) "Hello" 2) "World"

3. SISMEMBER:判断元素是否存在于集合中

作用:判断一个元素是否是集合的成员。

  • 语法SISMEMBER key member

  • 时间复杂度:O(1)

  • 返回值:1 表示元素存在,0 表示元素不存在或集合本身不存在

redis> SADD myset "one" (integer) 1 redis> SISMEMBER myset "one" (integer) 1 redis> SISMEMBER myset "two" (integer) 0

4. SCARD:获取集合的元素个数

作用:获取集合的基数(cardinality),也就是集合中元素的数量。

  • 语法SCARD key

  • 时间复杂度:O(1)

  • 返回值:集合中的元素个数

redis> SADD myset "Hello" (integer) 1 redis> SADD myset "World" (integer) 1 redis> SCARD myset (integer) 2

5. SPOP:随机删除并返回元素

作用:从集合中随机删除并返回一个或多个元素(因为集合是无序的,删除的元素是随机的)。

  • 语法SPOP key [count\]

  • 时间复杂度:O (N)(N 为 count 的值)

  • 返回值:被删除的元素

redis> SADD myset "one" (integer) 1 redis> SADD myset "two" (integer) 1 redis> SADD myset "three" (integer) 1 redis> SPOP myset "one" redis> SMEMBERS myset 1) "two" 2) "three" redis> SADD myset "four" (integer) 1 redis> SADD myset "five" (integer) 1 redis> SPOP myset 3 1) "four" 2) "five" 3) "two"

6. SMOVE:移动元素到另一个集合

作用:将一个元素从源集合移动到目标集合中。

  • 语法SMOVE source destination member

  • 时间复杂度:O(1)

  • 返回值:1 表示移动成功,0 表示元素不存在或移动失败

redis> SADD myset "one" (integer) 1 redis> SADD myset "two" (integer) 1 redis> SADD myotherset "three" (integer) 1 redis> SMOVE myset myotherset "two" (integer) 1 redis> SMEMBERS myset 1) "one" redis> SMEMBERS myotherset 1) "three" 2) "two"

7. SREM:删除集合中的指定元素

作用:从集合中删除一个或多个指定的元素。

  • 语法SREM key member [member \.\.\.\]

  • 时间复杂度:O (N)(N 为要删除的元素个数)

  • 返回值:本次操作成功删除的元素个数

redis> SADD myset "one" (integer) 1 redis> SADD myset "two" (integer) 1 redis> SADD myset "three" (integer) 1 redis> SREM myset "one" (integer) 1 redis> SMEMBERS myset 1) "two" 2) "three"

三、集合间的高级操作:交集、并集、差集

这是 Redis Set 最强大的功能之一,支持多个集合之间的数学运算,比如交集(inter)、并集(union)、差集(diff)。

1. SINTER:获取多个集合的交集

作用:返回所有给定集合的交集元素。

  • 语法SINTER key [key \.\.\.\]

  • 时间复杂度:O (N*M)(N 是最小集合的元素个数,M 是集合的数量)

  • 返回值:交集的元素列表

redis> SADD key1 "a" (integer) 1 redis> SADD key1 "b" (integer) 1 redis> SADD key1 "c" (integer) 1 redis> SADD key2 "c" (integer) 1 redis> SADD key2 "d" (integer) 1 redis> SADD key2 "e" (integer) 1 redis> SINTER key1 key2 1) "c"

2. SINTERSTORE:将交集结果保存到目标集合

作用:和SINTER功能类似,但会把交集结果存储到指定的目标集合中,而不是直接返回。

  • 语法SINTERSTORE destination key [key \.\.\.\]

  • 时间复杂度:O(N*M)

  • 返回值:交集中元素的个数

redis> SADD key1 "a" (integer) 1 redis> SADD key1 "b" (integer) 1 redis> SADD key1 "c" (integer) 1 redis> SADD key2 "c" (integer) 1 redis> SADD key2 "d" (integer) 1 redis> SADD key2 "e" (integer) 1 redis> SINTERSTORE key key1 key2 (integer) 1 redis> SMEMBERS key 1) "c"

3. SUNION:获取多个集合的并集

作用:返回所有给定集合的并集元素(合并所有元素并去重)。

  • 语法SUNION key [key \.\.\.\]

  • 时间复杂度:O (N)(N 是所有集合元素的总数)

  • 返回值:并集的元素列表

redis> SADD key1 "a" (integer) 1 redis> SADD key1 "b" (integer) 1 redis> SADD key1 "c" (integer) 1 redis> SADD key2 "c" (integer) 1 redis> SADD key2 "d" (integer) 1 redis> SADD key2 "e" (integer) 1 redis> SUNION key1 key2 1) "a" 2) "b" 3) "c" 4) "d" 5) "e"

4. SUNIONSTORE:将并集结果保存到目标集合

作用:和SUNION功能类似,但会把并集结果存储到指定的目标集合中。

  • 语法SUNIONSTORE destination key [key \.\.\.\]

  • 时间复杂度:O(N)

  • 返回值:并集中元素的个数

redis> SADD key1 "a" (integer) 1 redis> SADD key1 "b" (integer) 1 redis> SADD key1 "c" (integer) 1 redis> SADD key2 "c" (integer) 1 redis> SADD key2 "d" (integer) 1 redis> SADD key2 "e" (integer) 1 redis> SUNIONSTORE key key1 key2 (integer) 5 redis> SMEMBERS key 1) "a" 2) "b" 3) "c" 4) "d" 5) "e"

5. SDIFF:获取多个集合的差集

作用:返回第一个集合与其他集合的差集元素(只保留第一个集合中独有的元素)。

  • 语法SDIFF key [key \.\.\.\]

  • 时间复杂度:O(N)

  • 返回值:差集的元素列表

redis> SADD key1 "a" (integer) 1 redis> SADD key1 "b" (integer) 1 redis> SADD key1 "c" (integer) 1 redis> SADD key2 "c" (integer) 1 redis> SADD key2 "d" (integer) 1 redis> SADD key2 "e" (integer) 1 redis> SDIFF key1 key2 1) "a" 2) "b"

6. SDIFFSTORE:将差集结果保存到目标集合

作用:和SDIFF功能类似,但会把差集结果存储到指定的目标集合中。

  • 语法SDIFFSTORE destination key [key \.\.\.\]

  • 时间复杂度:O(N)

  • 返回值:差集中元素的个数

redis> SADD key1 "a" (integer) 1 redis> SADD key1 "b" (integer) 1 redis> SADD key1 "c" (integer) 1 redis> SADD key2 "c" (integer) 1 redis> SADD key2 "d" (integer) 1 redis> SADD key2 "e" (integer) 1 redis> SDIFFSTORE key key1 key2 (integer) 2 redis> SMEMBERS key 1) "a" 2) "b"

四、Set 命令速查表

这里整理了所有常用的 Set 命令,方便大家快速查阅:

命令功能描述时间复杂度
SADD key member [\.\.\.\]添加元素到集合O(1)
SMEMBERS key获取集合所有元素O(N)
SISMEMBER key member判断元素是否存在O(1)
SCARD key获取集合元素个数O(1)
SPOP key [count\]随机删除并返回元素O (N)(N 为 count)
SMOVE src dest member移动元素到另一个集合O(1)
SREM key member [\.\.\.\]删除指定元素O (N)(N 为删除的元素数)
SINTER key1 key2 [\.\.\.\]获取多个集合的交集O(N*M)
SINTERSTORE dest key1 [\.\.\.\]存储交集结果到目标集合O(N*M)
SUNION key1 key2 [\.\.\.\]获取多个集合的并集O(N)
SUNIONSTORE dest key1 [\.\.\.\]存储并集结果到目标集合O(N)
SDIFF key1 key2 [\.\.\.\]获取多个集合的差集O(N)
SDIFFSTORE dest key1 [\.\.\.\]存储差集结果到目标集合O(N)

五、Set 集合的底层编码实现

Redis 的 Set 类型有两种底层编码方式,会根据场景自动切换:

  1. intset(整数集合):当集合中的元素都是整数,且元素个数不超过 512 个时,Redis 会使用intset编码存储,这种方式非常节省内存。

    127.0.0.1:6379> SADD setkey 1 2 3 4 (integer) 4 127.0.0.1:6379> OBJECT encoding setkey "intset"
  2. hashtable(哈希表):当集合中的元素包含非整数,或者元素个数超过 512 个时,Redis 会自动切换为hashtable编码,以保证读写性能。

    127.0.0.1:6379> SADD setkey 1 2 3 4 ... (添加超过512个元素) 127.0.0.1:6379> OBJECT encoding setkey "hashtable"

六、Set 集合的实战场景

Set 集合的特性,让它在很多业务场景下都能大显身手,这里举几个常见的例子:

1. 给用户添加兴趣标签

我们可以用 Set 存储用户的兴趣标签,天然去重,添加 / 删除都很方便:

SADD user:1:tags tag1 tag2 tag3 SADD user:1:tags tag1 tag4 # 重复的tag1会被忽略

2. 给标签添加用户

反过来,也可以用 Set 存储每个标签下的用户列表:

SADD tag:1:users user:1 user:2 user:3 SADD tag:2:users user:1 user:4 user:9

3. 计算用户的共同好友 / 共同兴趣

利用 Set 的交集功能,我们可以轻松计算两个用户的共同兴趣标签:

# 计算user:1和user:2的共同兴趣 SINTER user:1:tags user:2:tags

这种场景在社交平台、推荐系统中非常常见,比如:

  • 计算两个用户的共同好友

  • 找出同时关注了多个话题的用户

  • 统计用户的共同兴趣,实现个性化推荐


总结

Redis 的 Set 集合虽然结构简单,但功能非常强大:无序、去重、支持丰富的集合运算,在标签系统、好友关系、数据去重等场景中都有不可替代的优势。掌握好这些命令和底层原理,就能在开发中灵活运用,写出更高效、更优雅的代码。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/12 21:39:07

别让查重和AI率卡住你的毕业!百考通AI的精准解决方案

每到毕业季,总有一场无声的战役悄然打响——它不是论文开题的迷茫,也不是数据收集的奔波,而是最后那道看似技术性、却足以让无数人熬红双眼的关卡:论文查重与AIGC检测。你是否也经历过这些场景:对着知网飘红的报告逐字…

作者头像 李华
网站建设 2026/5/12 21:37:15

转码使用教程

转换小程序使用说明 使用功能列表使用方式: 发送url链接/小程序分享/固定格式(微信小卡片)即可进行转换 链接生成二维码 条件:http或者https开头的链接小程序转普通二维码/详细信息/MP短链/小程序链/小程序码MP短链转普通二维码/详细信息/小程序链/小程序…

作者头像 李华
网站建设 2026/5/12 21:35:09

对比按量计费与TokenPlan套餐在长期项目中的成本观测差异

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 对比按量计费与TokenPlan套餐在长期项目中的成本观测差异 在持续数月的AI应用开发项目中,成本的可预测性与可控性是团队…

作者头像 李华
网站建设 2026/5/12 21:34:15

坏了,黑客学会用AI写外挂了

昨天刚聊完程序员为了省那23万Token账单连夜跑路的事儿,今天又出大事了。 而且这次不是钱包的问题——是有人在用AI造“数字万能钥匙”,想捅谁家窗户就捅谁家窗户。 听完你可能会想把家里智能门锁也换成铁锁头。 连坏人都开始用AI打工了?凌晨…

作者头像 李华
网站建设 2026/5/12 21:31:53

AI崛起,程序员还有出路吗?

今年的程序员可以说是最焦虑的一个群体了,面试找工作投简历没人理,有面试机会也面试不过,面试进去还干不长...于是,程序员们纷纷直呼:互联网寒冬又双叒叕来了,环境不好努力也没用躺平算了。真的是这样吗&am…

作者头像 李华
网站建设 2026/5/12 21:26:42

绝影马解析:亚马逊 Rufus 入局 AI 搜索 卖家流量规则大变局

2026 年亚马逊正式将Rufus深度整合进主搜索栏,开启AI 摘要 商品列表混合搜索新模式,跨境卖家的流量分发逻辑迎来底层重构,绝影马带大家拆解此次行业重大变革。此前Rufus只是独立 AI 导购助手,如今直接嵌入搜索首页,用…

作者头像 李华