当前位置: 首页 > news >正文

Redis 核心数据结构(四)——Set 与 Sorted Set,去重与排名神器

集合帮你自动去重,有序集合还能帮你排个名——排行榜、共同好友、标签系统,Set / Sorted Set 一把搞定!

本次导航

  • Set:无序、唯一
  • Sorted Set:带分数的 Set,按分数排序
  • 核心命令:SADDSINTERZADDZRANGEZRANK
  • 内部编码:intset vs hashtable,ziplist vs skiplist
  • 实战场景:共同好友、用户标签、实时排行榜、延时队列
  • 图解:交并差集 & 排行榜结构

发车前提醒:Set 和 Sorted Set 是 Redis 里“算法感”最强的两个结构,但用起来特别爽。

一、Set——无序且唯一

Set 就是一个自动去重的集合,里面的元素没有顺序,也不重复。你可以往里塞一堆东西,Redis 帮你保证每个元素只出现一次。

内部编码

  • 元素都是整数且数量少 →intset(紧凑数组,省内存)
  • 其他情况 →hashtable(和 Hash 一样)

常用命令

命令功能
SADD key member [member...]添加一个或多个元素
SREM key member [member...]移除元素
SISMEMBER key member判断是否存在
SMEMBERS key获取所有元素(慎用,可能慢)
SCARD key获取元素个数
SINTER key1 key2取交集
SUNION key1 key2取并集
SDIFF key1 key2取差集(key1 里有但 key2 没有的)
SRANDMEMBER key count随机取 count 个元素
SPOP key随机弹出一个元素

动手试试

SADD fruits"apple""banana""orange"SADD tropical"banana""mango""coconut"# 取交集(既是水果又是热带水果)SINTER fruits tropical# 返回 "banana"# 取并集SUNION fruits tropical# "apple","banana","orange","mango","coconut"# 取差集(水果里不属于热带的)SDIFF fruits tropical# "apple","orange"

上图很直观的表达了集合关系。

二、Set 实战场景

场景1:共同好友(社交应用)

假设用户 A 的好友集合是friends:A,用户 B 的是friends:B

SADD friends:A"U1""U2""U3""U4"SADD friends:B"U3""U4""U5""U6"# 共同好友SINTER friends:A friends:B# U3, U4# A 可能认识的人(B 的好友减去 A 的好友)SDIFF friends:B friends:A# U5, U6

场景2:用户标签 / 兴趣推荐

给用户打标签,然后根据标签交集推荐内容:

SADD user:1001:tags"tech""gaming""music"SADD user:1002:tags"gaming""sports""movie"# 相同标签SINTER user:1001:tags user:1002:tags# "gaming"# 推荐:取 user:1002 有但 user:1001 没有的标签SDIFF user:1002:tags user:1001:tags# "sports","movie"

场景3:抽奖 / 随机抽样

抽奖活动场景使用率相当的高,比如从参与用户集合里随机抽一个:

SADD lottery"user1""user2""user3""user4""user5"SRANDMEMBER lottery1# 随机抽一个,不删除SPOP lottery# 随机抽一个并移除(中奖后出局)

三、Sorted Set——带排名的 Set

Sorted Set(有序集合)在 Set 的基础上,给每个元素绑定了一个score(分数),然后按照分数从小到大排序。

分数相同则按字典序。

内部编码

  • 元素少且分数相近 →ziplist(压缩列表)
  • 元素多时 →skiplist + hashtable(跳表保证有序,哈希表保证快速查找)

常用命令

命令功能
ZADD key score member [score member...]添加元素并指定分数
ZRANGE key start stop [WITHSCORES]按分数升序取指定范围
ZREVRANGE按分数降序取
ZRANK key member获取元素排名(从0开始,升序)
ZREVRANK获取元素排名(降序)
ZSCORE key member获取元素分数
ZINCRBY key increment member增加元素分数
ZREM key member删除元素
ZCOUNT key min max统计分数在区间内的元素数量
ZRANGEBYSCORE按分数区间取元素

动手试试

# 游戏排行榜:玩家分数ZADD leaderboard100"Alice"200"Bob"150"Charlie"# 按分数从低到高取全部(带分数)ZRANGE leaderboard0-1WITHSCORES# 1) "Alice" 2) "100" 3) "Charlie" 4) "150" 5) "Bob" 6) "200"# 按分数从高到低(排名靠前的)ZREVRANGE leaderboard02WITHSCORES# "Bob" 200, "Charlie" 150, "Alice" 100# 查看 Alice 的排名(升序排名,0表示第一名)ZRANK leaderboard"Alice"# 0ZREVRANK leaderboard"Alice"# 2(倒数第一)

四、Sorted Set 实战场景

场景1:实时排行榜(游戏、热度)

每次玩家得分,就用ZINCRBY增加分数:

# 玩家 Bob 获得 50 分ZINCRBY game_scores50"Bob"# 获取 Top 5ZREVRANGE game_scores04WITHSCORES

场景2:延时队列(拿分数当时间戳)

把任务作为 member,执行时间戳作为 score。消费者定期用ZRANGEBYSCORE取到期的任务:

# 添加延时任务:当前时间戳 + 延迟秒数ZADD delay_queue1735689600"send_email:user1001"ZADD delay_queue1735690000"clean_cache"# 消费者(每隔几秒执行)# 取出当前时间戳之前的所有任务ZRANGEBYSCORE delay_queue01735689700# 然后删除取出的任务(ZREM)

场景3:商品热度 / 滑动窗口限流

用 Sorted Set 存储用户在某时间窗口内的访问记录,score 是时间戳:

# 用户 1001 在时间戳 1735689600 访问了一次ZADD rate_limit:10011735689600"req_1"# 清理 60 秒前的记录ZREMRANGEBYSCORE rate_limit:100101735689540# 统计最近 60 秒内的请求数ZCOUNT rate_limit:10011735689540+inf

五、Set vs Sorted Set 选择指南

需求用哪个理由
只要去重,不要排序Set内存更省,操作更快
需要判断元素是否存在SetO(1) 时间复杂度
需要按分数排序Sorted Set自带排序,支持范围查询
需要频繁取 Top NSorted SetZREVRANGE极快
需要按时间戳排序做队列Sorted Set用 score 存时间戳
需要集合运算(交并差)SetSorted Set 不支持直接集合运算

📢 觉得有用?

热烈欢迎:

  • 点赞 + 在看支持一下
  • 关注公众号,接收第一首博客文章
  • 留言告诉我你遇到过哪些有意思的排行榜 / 去重场景

我们下期见!🚀

http://www.jsqmd.com/news/932917/

相关文章:

  • GLM3大语言模型代码解析:深入理解推理pipeline的实现原理
  • 2026年不锈钢水箱定制好用吗,我小区二次供水靠谱厂家排名 - myqiye
  • 别再重装系统了!Win11更新搞乱Ubuntu引导?5分钟BIOS设置救回你的双系统
  • Ultimate Vocal Remover GUI:专业级人声分离工具完整指南
  • Ubuntu 22.04 上 OVS 服务启动失败?手把手教你排查并修复 ‘ovsdb-server.service is not running‘
  • ALMA-7B性能优化技巧:7个方法提升翻译速度和准确率
  • 从初代架构到大模型时代,英伟达GPU底层架构演进与核心逻辑深度解析
  • 量子近似优化算法(QAOA)原理与无辅助量子比特实现
  • OpenCore Legacy Patcher技术方案:为老款Mac实现现代macOS完整兼容
  • 2026北京商铺瓷砖空鼓翘边维修机构排名 十六区商业修缮服务商盘点 - 吉修匠
  • 深度强化学习在四旋翼无人机球类杂耍控制中的应用
  • 公共建筑室外装饰装修工程总承包服务费用多少 - myqiye
  • 深入硬件层:揭秘Windows高精度计时API QueryPerformanceCounter背后的TSC与多计时器机制
  • RAID 10和RAID 01,一字之差天壤之别!手把手教你用Windows存储空间和群晖DSM实操验证
  • 如何让微信聊天记录成为你的永久数字资产?WeChatMsg本地备份完整指南
  • 从轨迹抖动到安全指标:手把手拆解一个自动驾驶决策模块的代码实现(附Python伪代码)
  • 基于 LightGBM + Streamlit 的校园食堂销量预测与备餐建议系统实战
  • pi-subagents 代码审查:保持代码质量的完整审查流程
  • Czkawka终极清理工具:5分钟掌握免费开源的文件管理神器
  • 2026年武昌个人处理保险合同纠纷的律师如何选择 - myqiye
  • 从0到1部署Mathmate-7B-DELLA-ORPO-D-openmind:完整环境配置与推理教程
  • 从‘相爱相杀’到‘和平共处’:深入理解Linux中NetworkManager与network服务的职责边界与协作配置
  • 解决Linux内核模块依赖编译报错:详解EXPORT_SYMBOL与Module.symvers的拷贝时机
  • 未来展望:Hy-MT2技术路线图与腾讯混元翻译模型的发展方向
  • WinServer 2012 R2在浪潮服务器上的“后安装”实战:驱动、网络与远程桌面配置全记录
  • LeNet-5项目实战:从零到一的图像分类模型部署教程
  • 保姆级教程:手把手教你用U盘给服务器安装ESXi 7.0(附静态IP配置与许可证激活)
  • 从环境依赖到一键部署:lx-music-desktop容器化实践指南
  • 德克威尔EX1110远程IO模块PROFINET组态用GSDML文件(v1.1.6,2021年发布)
  • 2026年爱多电梯安装工程口碑排名,用户评价良好 - myqiye