Redis的有序集合:不仅不重复,还能排座次!排行榜的秘密武器!
mhr18 2025-05-26 17:30 13 浏览 0 评论
你是不是常常在游戏中看到“战力排行榜”、“财富榜”?在新闻客户端里刷到“热点新闻榜”?在音乐APP里发现“热门单曲榜”?这些让人欲罢不能的“榜单”,背后都有一个共同的秘密:数据不仅要不重复,还要能根据某种标准(比如分数、时间)进行排序!
如果让你来设计这些排行榜,你可能会想到用数据库:每次更新分数就去数据库里修改,然后每次查询排行榜就用ORDER BY排序。但是,当游戏玩家达到千万、上亿,或者新闻每秒钟都在更新时,这种方式分分钟让你的数据库崩溃!
这时候,Redis的“有序集合”就如同武林中的绝世高手,以其独有的“排座次”能力,轻松化解这些难题!
什么是Redis的“有序集合”?——“带分数的独一无二排队机”
在Redis中,有序集合(Sorted Set,也常简称为ZSet)是一个不重复的、每个成员都关联一个分数(Score)的集合。它像一个特别的“排队机”:
- 不重复(Unique): 就像我们之前讲的普通“集合”一样,有序集合里的每个成员(Member)都是独一无二的。你不能有两个相同的成员。
- 有分数(Score): 这是它最与众不同的地方!每个成员都带有一个浮点数类型的“分数”。这个分数就是决定成员排名的依据。
- 有序(Ordered): 最神奇的地方!有序集合会自动根据成员的分数进行排序。分数小的在前,分数大的在后(默认是升序)。如果分数相同,则按照成员的字典序(字母顺序)进行排序。
你可以把它想象成一场比赛,每个参赛选手(成员)都有一个唯一的名字,并且他们根据自己的比赛成绩(分数)自动站到了对应的名次上。
它和普通集合有什么区别?
普通集合只有成员,无序,不能根据某个标准排序。
有序集合:成员不仅不重复,还多了个“分数”属性,可以根据分数自动排序。
它和列表有什么区别?
列表:有序,但可重复,且没有“分数”的概念。成员的顺序完全由你添加或移除的顺序决定。
有序集合:成员不重复,且其顺序是由“分数”自动决定的。
核心操作揭秘:玩转“排行榜”的秘密武器!
有序集合的操作命令,都围绕着“成员”和“分数”展开:
1. 添加/更新成员和分数:ZADD (Sorted Set ADD)
这是有序集合最核心的命令。你可以添加一个新成员并给它打分,也可以更新一个已有成员的分数。
- 命令示例:
ZADD game_leaderboard 1000 user:zhangsan (张三得分1000)
ZADD game_leaderboard 1200 user:lisi (李四得分1200)
ZADD game_leaderboard 950 user:wangwu (王五得分950)
ZADD game_leaderboard 1500 user:lisi (李四分数更新为1500,因为成员已存在)
2. 获取指定范围内的成员(按排名):ZRANGE/ZREVRANGE
查询排行榜最常用的命令!你可以获取排名靠前或靠后的成员列表。
- ZRANGE key start stop [WITHSCORES]: 获取从低分到高分的指定范围成员。
- ZREVRANGE key start stop [WITHSCORES]: 获取从高分到低分的指定范围成员(通常用于排行榜)。
- 命令示例(获取前3名,带分数):
ZREVRANGE game_leaderboard 0 2 WITHSCORES (0 2表示索引从0到2,也就是前3个) - 返回结果可能像这样:
- "user:lisi"
- "1500"
- "user:zhangsan"
- "1000"
- "user:wangwu"
- "950"
3. 获取指定分数范围的成员:
ZRANGEBYSCORE/ZREVRANGEBYSCORE
筛选出分数在某个区间的成员,比如所有得分超过1000的玩家。
- 命令示例(获取分数在1000到1500之间的成员):
ZRANGEBYSCORE game_leaderboard 1000 1500 WITHSCORES - 返回: 所有分数介于1000和1500之间的成员及其分数。
4. 获取成员的分数:ZSCORE
查询某个成员的当前分数。
- 命令示例:
ZSCORE game_leaderboard user:lisi - 返回: "1500"
5. 获取成员的排名:ZRANK/ZREVRANK
查询某个成员在排行榜中的具体位置(排名)。
- ZRANK key member: 从低分到高分(升序)的排名(索引从0开始)。
- ZREVRANK key member: 从高分到低分(降序)的排名(索引从0开始,通常用于排行榜)。
- 命令示例(查询李四在降序排行榜中的排名):
ZREVRANK game_leaderboard user:lisi - 返回: "0" (表示李四是第1名,因为索引从0开始)
6. 增加成员分数:ZINCRBY (Sorted Set INCRement BY)
这是动态排行榜的灵魂!当成员分数发生变化时,不需要先取出来加,再存回去,而是直接进行原子性的增减。
- 命令示例(张三又得了500分):
ZINCRBY game_leaderboard 500 user:zhangsan - 此时张三的分数将从1000变为1500,并且在排行榜中的位置会自动调整。
7. 移除成员:ZREM (Sorted Set REMOVE)
将成员从有序集合中移除。
- 命令示例:
ZREM game_leaderboard user:wangwu
经典应用场景:有序集合的“高光时刻”!
场景一:实时游戏排行榜/积分榜
这毋庸置疑是有序集合最经典、最直观的应用。无论是每日榜、周榜、月榜,还是总榜,都能轻松实现。
- 操作: 玩家每获得积分或战力提升,就用ZINCRBY更新其分数。展示排行榜时,用ZREVRANGE获取TOP N玩家。
- 亮点: 高并发下,分数更新是原子性的,不会出现数据不一致。排名实时更新,用户体验极佳。
场景二:热门商品/新闻排行
不仅仅是游戏,任何需要“热门”的概念,都可以用有序集合。
- 分数设计: 可以是商品的销量、文章的阅读量、点赞数等。
- 衰减机制: 为了让榜单更“实时”和“新鲜”,可以给分数加上时间衰减因子。例如,每天定时对所有成员的分数乘以一个0.9的系数,这样老旧的热点就会逐渐沉淀下去,新的热点才能浮上来。
- 操作: 每当商品被购买、文章被阅读,ZINCRBY其分数。同时,可以结合定时任务,对所有成员的分数进行定期衰减。
场景三:用户等级/经验值系统
根据用户的经验值或活跃度,划分不同的等级,并展示其在同等级内的排名。
- 操作: 用户完成任务、签到等,增加经验值,ZINCRBY更新分数。
- 筛选: 可以用ZRANGEBYSCORE筛选出某个经验值范围内的用户,再在此范围内进行排名展示。
场景四:带有权重的标签/分类系统
在某些推荐系统中,用户可能对某些标签有更高的偏好。
- 操作: 将标签作为成员,用户对标签的偏好程度作为分数。根据用户的行为(点击、购买),ZINCRBY相关标签的分数,从而为用户推荐更符合其偏好的内容。
总结:有序集合,让数据“活”起来!
看到了吗?Redis的“有序集合”,凭借其“不重复成员 + 分数 + 自动排序”的独特组合,成为了处理各种“排行榜”、“热门榜单”、“积分体系”的利器。它让原本静态的数据,能够根据实时的变化“活”起来,动态地展现出它们的价值和排名。
它就像一位专业的“排名大师”,总能将海量数据梳理得井井有条,将最受关注、最具价值的信息呈现在用户面前,这正是许多“爆款”应用的核心魅力所在。
至此,我们已经完整地探索了Redis的五大基本数据类型:字符串、列表、哈希、集合、有序集合。它们各自都有独特的优势和应用场景,相互配合,构建起了Redis这座强大而灵活的数据存储和处理堡垒。
希望通过这一系列的科普文章,你对Redis不再感到陌生,而是对它充满好奇和兴趣。你会发现,那些看似复杂的“高科技”,其实都是由这些基础的“积木”搭建而成的。学会使用这些积木,你也能搭建出属于自己的“爆款”应用!
感谢你的阅读,我们下期再见!
相关推荐
- 一文读懂Prometheus架构监控(prometheus监控哪些指标)
-
介绍Prometheus是一个系统监控和警报工具包。它是用Go编写的,由Soundcloud构建,并于2016年作为继Kubernetes之后的第二个托管项目加入云原生计算基金会(C...
- Spring Boot 3.x 新特性详解:从基础到高级实战
-
1.SpringBoot3.x简介与核心特性1.1SpringBoot3.x新特性概览SpringBoot3.x是建立在SpringFramework6.0基础上的重大版...
- 「技术分享」猪八戒基于Quartz分布式调度平台实践
-
点击原文:【技术分享】猪八戒基于Quartz分布式调度平台实践点击关注“八戒技术团队”,阅读更多技术干货1.背景介绍1.1业务场景调度任务是我们日常开发中非常经典的一个场景,我们时常会需要用到一些不...
- 14. 常用框架与工具(使用的框架)
-
本章深入解析Go生态中的核心开发框架与工具链,结合性能调优与工程化实践,提供高效开发方案。14.1Web框架(Gin,Echo)14.1.1Gin高性能实践//中间件链优化router:=...
- SpringBoot整合MyBatis-Plus:从入门到精通
-
一、MyBatis-Plus基础介绍1.1MyBatis-Plus核心概念MyBatis-Plus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提...
- Seata源码—5.全局事务的创建与返回处理
-
大纲1.Seata开启分布式事务的流程总结2.Seata生成全局事务ID的雪花算法源码3.生成xid以及对全局事务会话进行持久化的源码4.全局事务会话数据持久化的实现源码5.SeataServer创...
- Java开发200+个学习知识路线-史上最全(框架篇)
-
1.Spring框架深入SpringIOC容器:BeanFactory与ApplicationContextBean生命周期:实例化、属性填充、初始化、销毁依赖注入方式:构造器注入、Setter注...
- OpenResty 入门指南:从基础到动态路由实战
-
一、引言1.1OpenResty简介OpenResty是一款基于Nginx的高性能Web平台,通过集成Lua脚本和丰富的模块,将Nginx从静态反向代理转变为可动态编程的应用平台...
- 你还在为 Spring Boot3 分布式锁实现发愁?一文教你轻松搞定!
-
作为互联网大厂后端开发人员,在项目开发过程中,你有没有遇到过这样的问题:多个服务实例同时访问共享资源,导致数据不一致、业务逻辑混乱?没错,这就是分布式环境下常见的并发问题,而分布式锁就是解决这类问题的...
- 近2万字详解JAVA NIO2文件操作,过瘾
-
原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。从classpath中读取过文件的人,都知道需要写一些读取流的方法,很是繁琐。最近使用IDEA在打出.这个符号的时候,一行代...
- 学习MVC之租房网站(十二)-缓存和静态页面
-
在上一篇<学习MVC之租房网站(十一)-定时任务和云存储>学习了Quartz的使用、发邮件,并将通过UEditor上传的图片保存到云存储。在项目的最后,再学习优化网站性能的一些技术:缓存和...
- Linux系统下运行c++程序(linux怎么运行c++文件)
-
引言为什么要在Linux下写程序?需要更多关于Linux下c++开发的资料请后台私信【架构】获取分享资料包括:C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdf...
- 2022正确的java学习顺序(文末送java福利)
-
对于刚学习java的人来说,可能最大的问题是不知道学习方向,每天学了什么第二天就忘了,而课堂的讲解也是很片面的。今天我结合我的学习路线为大家讲解下最基础的学习路线,真心希望能帮到迷茫的小伙伴。(有很多...
- 一个 3 年 Java 程序员 5 家大厂的面试总结(已拿Offer)
-
前言15年毕业到现在也近三年了,最近面试了阿里集团(菜鸟网络,蚂蚁金服),网易,滴滴,点我达,最终收到点我达,网易offer,蚂蚁金服二面挂掉,菜鸟网络一个月了还在流程中...最终有幸去了网易。但是要...
- 多商户商城系统开发全流程解析(多商户商城源码免费下载)
-
在数字化商业浪潮中,多商户商城系统成为众多企业拓展电商业务的关键选择。这类系统允许众多商家在同一平台销售商品,不仅丰富了商品种类,还为消费者带来更多样的购物体验。不过,开发一个多商户商城系统是个复杂的...
你 发表评论:
欢迎- 一周热门
-
-
Redis客户端 Jedis 与 Lettuce
-
高并发架构系列:Redis并发竞争key的解决方案详解
-
redis如何防止并发(redis如何防止高并发)
-
开源推荐:如何实现的一个高性能 Redis 服务器
-
redis安装与调优部署文档(WinServer)
-
Redis 入门 - 安装最全讲解(Windows、Linux、Docker)
-
一文带你了解 Redis 的发布与订阅的底层原理
-
Redis如何应对并发访问(redis控制并发量)
-
oracle数据库查询Sql语句是否使用索引及常见的索引失效的情况
-
Java SE Development Kit 8u441下载地址【windows版本】
-
- 最近发表
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)