一、Redis Set 是什么
Set = 不重复 + 无顺序的集合
一个自动去重、不关心顺序的容器
二、Set 和 List 的本质区别
| 对比项 | List | Set |
|---|---|---|
| 是否允许重复 | ✅ 允许 | ❌ 不允许 |
| 是否有顺序 | ✅ 有顺序(下标) | ❌ 无序 |
| 能否按下标访问 | ✅ LINDEX | ❌ 不支持 |
| 是否支持集合运算 | ❌ | ✅ 交集 / 并集 / 差集 |
| 典型使用场景 | 消息队列、时间线 | 去重、关系、标签 |
三、Set 能干什么
交集(共同好友)
SINTER user:1:friends user:2:friends并集(所有好友)
SUNION user:1:friends user:2:friends差集(你有我没有)
SDIFF user:1:friends user:2:friends四、底层结构一:整数集合
使用条件(必须同时满足)
所有元素都是整数
元素个数 < 512(默认,可配置)
本质:连续内存数组
特点:
有序存储(但对外仍然无序)
紧凑、节省内存
使用二分查找
只支持整数
五、底层结构二:哈希表
什么时候用?
元素不是纯整数
或元素数量很多
优点
O(1) 级别的增删查
支持任意字符串
支持大规模数据
缺点
内存占用比 intset 高
有 rehash 成本
六、两种实现对比总结
| 维度 | intset | hash table |
|---|---|---|
| 元素类型 | 仅整数 | 任意 |
| 数据规模 | 小(<512) | 大 |
| 内存占用 | 极低 | 较高 |
| 查询方式 | 二分查找 | 哈希 |
| 是否自动升级 | → hash | 不可降级 |
七、为什么抽奖活动非常适合用 Set?
抽奖的核心需求其实就 4 个字:
去重 + 随机
| 抽奖需求 | Set 特性 |
|---|---|
| 同一用户不能重复参与 | Set 天然去重 |
| 参与顺序无所谓 | Set 无序 |
| 随机抽人 | SRANDMEMBER / SPOP |
| 统计参与人数 | SCARD |