文章目录
背景
排行榜这个业务很常见,比如直播间中的“榜一大哥”、微信的步数排行榜、游戏的段位排行榜等等。
如下图为 CSDN 的排行榜,有全站综合热榜、领域内容榜、热门专栏榜…………各式各样。
使用MySQL实现排行榜
实现思路
直接使用MySQL中的order by
limit
关键字,对查询出来的数据进行排序并截取前多少名次
举个例子
select * from student order by score desc limit 10;
这条 SQL 就是查询了所有学生中分数最高的前十名,排序的字段为score
,排序的方向是desc
(降序)。
优点
- 实现简单:使用成本低,无需引入其他中间件。
- 查询能力强:利用 SQL 查询语言,可以灵活地构建复杂的查询语句来检索排行榜数据。
弊端
- 资源消耗:数据库资源是宝贵的,当业务对排行榜的实时性强,数据量大的时候,对数据库的性能消耗是非常大
复现
1)建表
CREATE TABLE `student` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`score` int(11) NOT NULL,
`name` varchar(11) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=100000 DEFAULT CHARSET=utf8mb4;
2)使用 navicat 生成 500w 数据
3)直接使用 order by
查询
平均在 2.3 秒左右,当然实际业务中可能会拼接多个查询条件和多张表,耗时会更长
4)优化:对 score 添加索引
创建索引也是一种加速查询的手段,在加上索引后平均耗时 0.6 秒左右
这只是一个最简单的场景,实际项目中的复杂度要复杂很多,执行速度也会慢很多。
当然这种怕排序需根据业务场景决定。对于小数据量且排序逻辑简单的场景(如博客文章按阅读量排序),直接使用 order by
limit
也是没问题的。
Redis 的 Sorted Set
什么是 Sorted Set
Redis 中的 Sorted Set 是一种有序集合,每个元素都关联一个分数score
,用于排序。
它类似于 Java 中的 HashMap,但增加了排序功能,其中 HashMap 存储键值对,而 Sorted Set 存储带分数的元素,通过分数排序。Sorted Set 支持范围查询和快速排序操作。
Sorted Set 常用命令
命令 | 介绍 |
---|---|
ZADD key score1 member1 score2 member2 … | 向指定有序集合添加一个或多个元素 |
ZCARD KEY | 获取指定有序集合的元素数量 |
ZSCORE key member | 获取指定有序集合中指定元素的 score 值 |
ZINTERSTORE destination numkeys key1 key2 … | 将给定所有有序集合的交集存储在 destination 中,对相同元素对应的 score 值进行 SUM 聚合操作,numkeys 为集合数量 |
ZUNIONSTORE destination numkeys key1 key2 … | 求并集,其它和 ZINTERSTORE 类似 |
ZDIFF destination numkeys key1 key2 … | 求差集,其它和 ZINTERSTORE 类似 |
ZRANGE key start end | 获取指定有序集合 start 和 end 之间的元素(score 从低到高) |
ZREVRANGE key start end | 获取指定有序集合 start 和 end 之间的元素(score 从高到底) |
ZREVRANK key member | 获取指定有序集合中指定元素的排名(score 从大到小排序) |
详细命令:https://redis.io/commands/?group=sorted-set 。
使用示例
1)添加数据
ZADD student_set 112.0 user1 100.0 user2 123.0 user3 100.0 user4 33.0 user5 993.0 user6
2)查看前五名
ZREVRANGE student_set 0 4
3)查看具体分数
ZSCORE student_set "user1"
4)查看具体排名
ZREVRANK student_set "user6"
5)对排名数据进行更新
ZINCRBY student_set +2 "user1"
对 “user1” 的分数做 +2 处理
标签:Set,Redis,排行榜,score,student,Sorted,排序 From: https://blog.csdn.net/m0_72918997/article/details/141503012