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」两个原则即可。

笔记加载中…