首页/数据/数据库速查/标签与共同关注场景(集合运算实战)
Redis 命令96 条

标签与共同关注场景(集合运算实战)

用 Set 实现标签系统:SADD 打标、SINTER 找同时命中多标签的对象;大规模标签建议按位图或搜索引擎承载。

数据库速查数据更新于 2026-10-13

用 Set 做标签是什么

标签系统的经典做法是「一个标签一个 Set」:把对象 ID 作为成员放进 tag:<标签名> 集合,于是「同时命中多个标签」就是集合交集 SINTER,「至少命中一个」是并集 SUNION,「只要第一个标签不要第二个」是差集 SDIFF。这种结构天然去重、支持 O(1) 的增删,缺点是集合规模大到百万级时,实时交集运算会变成慢命令。

基本信息

适用版本Redis 全版本(SINTERCARD 需 7.0+)
打标SADD tag:<标签> <对象ID>
交集SINTER / SINTERCARD 数量统计
并集与差集SUNION、SDIFF、SDIFFSTORE
去重集合天然去重,重复 SADD 不增加基数
规模上限单标签集合过大时交集成本高,需分片或改用检索引擎

典型使用场景

  • 内容推荐:找同时命中多个兴趣标签的文章或商品
  • 共同关注:两个用户的好友集合求交
  • 权限校验:角色集合与所需权限集合求交判断是否放行
  • 人群圈选:多个条件标签求交得到目标人群
  • 黑名单与白名单快速判断:SISMEMBER 单点判定 O(1)

实战

实战
SADD tag:redis post1 post2 post9
SADD tag:mysql post2 post3 post9

SINTER tag:redis tag:mysql        # post2 post9(两个标签都命中)
SUNION tag:redis tag:mysql        # 至少命中一个标签
SDIFF tag:redis tag:mysql         # 只有 redis 标签的
SINTERCARD 2 tag:redis tag:mysql  # 2:只取交集数量,省带宽

SISMEMBER tag:redis post1         # 1:单点判断是否命中标签
SCARD tag:redis                   # 单标签规模,判断是否过大

集合运算选择

需求命令注意
同时满足多标签SINTER / SINTERCARD结果集大小取最小集合规模
至少满足一个SUNION / SUNIONSTORE结果可能远大于单个集合
排除某标签SDIFF方向敏感,A 减 B 与 B 减 A 不同
只要数量SINTERCARD7.0+ 支持,避免把大结果集传回客户端
单标签判定SISMEMBERO(1),适合鉴权与前置校验
标签集合要按关注度预估规模:热点标签可能达到千万级成员,此时实时交集运算会让单线程阻塞。可用的缓解手段是把运算放到只读从库、离线预计算交集结果,或用搜索引擎承担标签检索。
不要把「多个标签」塞进一个 Set 当作多值字段:这样无法表达「同时满足多个标签」的语义,也无法按标签单独统计。正确结构是一标签一集合,对象 ID 作为成员。

易错点

  • 把所有标签塞进一个 Set:无法表达「同时满足多标签」,交集运算无从下手
  • 线上实时对大集合做 SINTER:慢命令拖住主线程,影响所有业务
  • 忽略 SUNION 的结果规模:两个百万级集合求并集,返回大数组可能打满带宽与内存
  • 用 Set 存有序数据:集合不保存顺序,需要排序或按时间取最近项的应改用 ZSet
  • 标签集合不做容量规划:热点标签无限增长,直到交集运算变成事故

数据来源与参考

  • Redis 官方文档: SINTER
  • Redis 官方文档: Set 使用模式

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌