全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-12 6 分钟 ✍️ juanwangdev

Redis集合

集合(Set)是无序、不重复的字符串集合,支持丰富的集合运算,适合标签、好友关系等场景。

结构概述

基本特点

Bash
- 无序字符串集合
- 元素不重复
- 支持集合运算(交、并、差)
- 单个集合最多2^32-1个元素

与List对比

Bash
List:有序、可重复、两端操作
Set:无序、不重复、集合运算

内部编码

intset编码

Bash
触发条件:
- 所有元素都是整数
- 元素数量 ≤ set-max-intset-entries(默认512)

特点:
- 紧凑连续内存
- 有序存储整数
- 查找O(logN)(二分查找)
- 内存效率极高

hashtable编码

Bash
触发条件:
- 包含非整数元素
- 或元素数量超过512

特点:
- 哈希表结构
- 查找O(1)
- 内存占用较大
- 无序存储

查看编码

Bash
SADD myset 1 2 3
OBJECT ENCODING myset
# 返回: "intset"

SADD myset "a"
OBJECT ENCODING myset
# 返回: "hashtable"(转为hashtable)

编码转换

intset转hashtable

Bash
# 条件1:添加非整数
SADD intset:demo 1 2 3
OBJECT ENCODING intset:demo  # "intset"
SADD intset:demo "string"
OBJECT ENCODING intset:demo  # "hashtable"

# 条件2:超过512个整数元素
for i in {1..513}; do
    SADD large:set $i
done
OBJECT ENCODING large:set  # "hashtable"

intset一旦转为hashtable,不可逆回intset。

应用场景

1. 标签系统

Bash
# 用户标签
SADD user:1000:tags "tech" "redis" "nosql"

# 文章标签
SADD article:500:tags "redis" "database" "cache"

# 查找标签下的文章
SADD tag:redis:articles "article:500"

# 查看用户标签
SMEMBERS user:1000:tags

2. 共同好友

Bash
# 用户好友列表
SADD user:1000:friends "user:1001" "user:1002" "user:1003"
SADD user:1001:friends "user:1002" "user:1004"

# 共同好友
SINTER user:1000:friends user:1001:friends
# 返回: "user:1002"

3. 可能认识的人

Bash
# 用户A的朋友
SADD user:A:friends "B" "C" "D"

# 用户B的朋友
SADD user:B:friends "A" "C" "E"

# 推荐好友:B的朋友中不是A朋友的
SDIFF user:B:friends user:A:friends
# 返回: "E"(A可能认识E)

4. 抽奖系统

Bash
# 参与用户
SADD lottery:users "user:1" "user:2" "user:3" "user:4" "user:5"

# 随机抽取获奖者(移除)
SPOP lottery:users
# 返回随机一个用户

# 随机抽取不移除
SRANDMEMBER lottery:users 2
# 随机返回2个用户(不移除)

5. 点赞/收藏

Bash
# 文章点赞用户
SADD article:500:likes "user:1000"

# 检查是否点赞
SISMEMBER article:500:likes "user:1000"
# 返回: 1

# 取消点赞
SREM article:500:likes "user:1000"

# 点赞数
SCARD article:500:likes

6. 唯一性检查

Bash
# 已注册邮箱
SADD emails:registered "alice@example.com" "bob@example.com"

# 检查邮箱是否已注册
SISMEMBER emails:registered "alice@example.com"
# 返回: 1(已注册)

集合运算

交集SINTER

Bash
# 多个集合的共同元素
SINTER set1 set2 set3

# 存储交集结果
SINTERSTORE result set1 set2

# 应用:共同好友、共同关注

并集SUNION

text
# 多个集合的所有元素
SUNION set1 set2

# 存储并集结果
SUNIONSTORE result set1 set2

# 应用:合并标签、合并好友

差集SDIFF

text
# 第一个集合相对于其他集合的差集
SDIFF set1 set2 set3
# 在set1但不在set2和set3的元素

# 存储差集结果
SDIFFSTORE result set1 set2

# 应用:推荐好友、补集

操作特点

O(1)操作

text
SADD:添加元素
SREM:删除元素
SISMEMBER:检查存在
SCARD:元素数量
SPOP:随机弹出

O(N)操作

text
SMEMBERS:获取全部元素
SINTER/SUNION/SDIFF:集合运算
# N为元素数量或集合大小

性能建议

大集合遍历

text
# 避免SMEMBERS获取大量元素
# 使用SSCAN分批遍历
SSCAN myset 0 COUNT 100

集合运算优化

text
- 小集合优先:SINTER从小集合开始
- 结果存储:使用STORE命令避免传输
- 分批处理:大数据集分批运算

控制集合大小

text
- 合理设计集合元素
- 及时清理无用元素
- 避免单个集合过大

注意事项

元素唯一性

text
# 重复添加返回0
SADD myset "a"
SADD myset "a"
# 返回: 0(已存在)

编码转换影响

text
intset编码高效但只支持整数
添加非整数会转为hashtable
转换后内存占用增加

无序性

text
SMEMBERS返回顺序不确定
不依赖元素顺序
排序需求用ZSet

编码对比

编码条件内存效率查找效率
intset全整数且≤512极高O(logN)
hashtable非整数或>512O(1)

与其他类型对比

特性SetListZSet
顺序无序有序按分数排序
重复不允许允许不允许
索引不支持支持按分数
运算交/并/差

要点总结

  • 集合是无序不重复的字符串集合
  • intset编码适合纯整数小集合(≤512),内存高效
  • hashtable编码适合非整数或大集合,O(1)查找
  • 应用场景:标签、好友关系、抽奖、点赞、唯一检查
  • SINTER交集、SUNION并集、SDIFF差集
  • 大集合用SSCAN遍历,避免SMEMBERS阻塞
  • intset添加非整数会转为hashtable,不可逆
  • 需要有序或排序场景使用ZSet而非Set

📝 发现内容有误?点击此处直接编辑

← 上一篇 Redis有序集合
下一篇 → Redis 核心特点
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库