Redis 集合 Set
Set 是元素唯一、无序的集合,底层用哈希实现,增删查都是 O(1)。它的价值不只是去重,更在于交、并、差等集合运算,能一次算清「共同好友」「好友推荐」这类问题。
添加与查看
SADD 添加成员(返回新增个数),SMEMBERS 查看全部:
SADD tags:1001 java python go
# 输出:(integer) 3
SADD tags:1001 java # 重复添加无效
# 输出:(integer) 0
SMEMBERS tags:1001
# 输出:1) "java" 2) "python" 3) "go"
SMEMBERS 返回顺序不保证,程序不要依赖集合的先后次序。
判断与删除
SISMEMBER 判存在,SREM 删除成员,SCARD 取个数:
SISMEMBER tags:1001 java
# 输出:(integer) 1
SREM tags:1001 go
# 输出:(integer) 1
SCARD tags:1001
# 输出:(integer) 2
判断登录态、优惠券是否已领等「是否存在」场景都用 SISMEMBER。
随机弹出
SRANDMEMBER 随机取不删除,SPOP 随机弹出删除,适合抽奖:
SADD draw:20240501 u1 u2 u3 u4 u5
# 输出:(integer) 5
SPOP draw:20240501 2 # 随机抽 2 人并移除(不重复中奖)
# 输出:1) "u3" 2) "u5"
SRANDMEMBER draw:20240501 # 随机看一个,不删
集合运算
SINTER 交集、SUNION 并集、SDIFF 差集,各有 STORE 版可把结果存到新键:
SADD a 1 2 3
SADD b 2 3 4
SINTER a b # 共同成员
# 输出:1) "2" 2) "3"
SUNION a b
# 输出:1) "1" 2) "2" 3) "3" 4) "4"
SDIFF a b # 在 a 不在 b
# 输出:1) "1"
SINTERSTORE c a b # 交集存到 c
# 输出:(integer) 2
「我和好友的共同关注」「两个标签都命中的用户」都可用交集一次算完。
常用命令一览
| 命令 | 作用 |
|---|---|
| SADD / SREM | 加 / 删成员 |
| SMEMBERS | 取全部成员 |
| SISMEMBER | 成员是否在集合 |
| SCARD | 集合大小 |
| SPOP / SRANDMEMBER | 随机弹出 / 随机查看 |
| SMOVE src dst m | 成员搬家 |
| SINTER / SUNION / SDIFF | 交集 / 并集 / 差集 |
典型场景
- 去重:文章点赞人集合,点过赞 SISMEMBER 判重;
- 标签系统:用户与文章的标签集合互查命中;
- 在线状态:每用户上线 SADD 到 online,下线 SREM,SCARD 即在线人数。
易踩坑
- 集合很大时别 SMEMBERS 全量拉取,会阻塞主线程,分批用 SSCAN;
- 集合「无序」,要按加入时间或分数排序请用 List 或 ZSet;
- 两个大集合做 SINTER 计算量不小,结果可 SINTERSTORE 缓存复用。
小结
Set 的看家本领是唯一性与集合运算:SADD/SISMEMBER 解决去重判存,SINTER/SUNION/SDIFF 解决关系计算。记住「大集合用 SSCAN、要排序换 ZSet」两个原则即可。