使用 Redis Zset 有序集合实现排行榜功能(SpringBoot环境)

目录

    • 一、前言
    • 二、Redis Zset 的基本操作
    • 三、通过Redis 命令模拟排行榜功能
      • 3.1、排行榜生成
      • 3.2、排行榜查询
    • 四、SpringBoot 使用 Redis Zset 有序集合实现排行榜功能

一、前言

      排行榜功能是非常常见的需求,例如商品售卖排行榜单、游戏中的积分排行榜、配送员完单排行榜等。实现排行榜功能需要高效地对大量数据进行排序和查询,如果直接进行数据库查询对应业务排行榜资源开销会非常大,一般会将对应榜单需要的数据做单独存储记录,查询时只要对榜单数据表进行遍历排序即可,因为榜单数据表的数据是无序的,还要对具体数据进行排序,并且每次数据变动都要更新表中数据,当数据量过大或者高并发时性能一般,要想高效地实现排行榜功能需要使用 Redis Zset 有序集合,可以非常高效方便地实现排行榜功能。

需要Redis常用命令集文章可以查看:https://blog.csdn.net/weixin_44606481/article/details/133672258

二、Redis Zset 的基本操作

# 添加以一个过着多个元素,score为评分,集合按照从低到高及进行排序,评分可以重复
zadd  <key> <score1> <value1> <score2> <value2># 获取有序集合中成员的数量
zcard <key># 统计score评分在某个范围内的数据的数量
zcount <key> <min> <max># 查一定范围的元素,end为-1时,查询所有,按照分数从小到大排序,withscores加上他,连着评分一起查出
zrange <key> <start> <end> [LIMIT offset count] [withscores]# 查一定范围的元素,end为-1时,查询所有,按照分数从大到小排序,withscores加上他,连着评分一起查出
zrevrange <key> <start> <end> [LIMIT offset count] [withscores]# 查询score评分在某个范围内的数据,从小到大排序,min 和 max 可以是 -inf 和 +inf来表示无穷小和无穷大,withscores加上他,连着评分一起查出
zrangebyscore <key> <min> <max> [withscores] [limit offset count]# 查询score评分在某个范围内的数据,从大到小排序,min 和 max 可以是 -inf 和 +inf来表示无穷小和无穷大,withscores加上他,连着评分一起查出
zrevrangebyscore  <key> <max> <min> [withscores] [limit offset count]# 为元素的score加上指定的增量
zincrby  <key> <increment> <value># 删除数据
zrem <key> <value1> <value2># 返回集合中value的排名,按分数递增排序。分数值最小者排名为0
zrank  <key> <value># 返回集合中value的排名,按分数递减排序。分数值最大者排名为0
zrevrank  <key> <value>

三、通过Redis 命令模拟排行榜功能

       这里模拟一个商品销量排行榜缓存key为PRODUCT:RANK:SALES,假设有6个商品,商品ID分别为 P001-P006。

3.1、排行榜生成

  • 1、初始化排行榜数据(为了演示这里先给每个商品销量设置0,一般在业务中会先将数据库中的销量数据查询出来初始化到排行榜中)
127.0.0.1:6379> zadd  PRODUCT:RANK:SALES 0 P001 0 P002 0 P003 0 P004 0 P005 0 P006
(integer) 6
  • 2、给商品ID为P002、P005、P006的商品分别添加销量7、2、9
127.0.0.1:6379> zincrby PRODUCT:RANK:SALES 7 P002
"7"
127.0.0.1:6379> zincrby PRODUCT:RANK:SALES 2 P005
"2"
127.0.0.1:6379> zincrby PRODUCT:RANK:SALES 9 P006
"9"

3.2、排行榜查询

  • 1、查询排行榜全部数据按照分数从大到小排序
127.0.0.1:6379> zrevrange PRODUCT:RANK:SALES 0 -1 withscores1) "P006"2) "9"3) "P002"4) "7"5) "P005"6) "2"7) "P004"8) "0"9) "P003"
10) "0"
11) "P001"
12) "0"
  • 2、查询排行榜销量前三的数据按照分数从大到小排序
127.0.0.1:6379> zrevrange PRODUCT:RANK:SALES 0 2 withscores
1) "P006"
2) "9"
3) "P002"
4) "7"
5) "P005"
6) "2"
  • 3、查询排行榜销量大于等于1的数据从小到大排序,并且进行分页,每页2条数据查询第1页
# 不分页
127.0.0.1:6379> zrangebyscore PRODUCT:RANK:SALES 1 +inf withscores
1) "P005"
2) "2"
3) "P002"
4) "7"
5) "P006"
6) "9"
# 分页 limit 0 2 (0:代表偏移量 2:显示条数)
127.0.0.1:6379> zrangebyscore PRODUCT:RANK:SALES 1 +inf withscores limit 0 2
1) "P005"
2) "2"
3) "P002"
4) "7"

四、SpringBoot 使用 Redis Zset 有序集合实现排行榜功能

需要SpringBoot集成Redis文章可以查看:https://blog.csdn.net/weixin_44606481/article/details/133907103

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.HashSet;
import java.util.Set;@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class RedisZSetTest {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;// 商品排行榜keyprivate String cacheKey = "PRODUCT:RANK:SALES";/*** 初始化排行榜*/@Testpublic void initRank() {// 初始化前先删除对应keyredisTemplate.delete(cacheKey);// 创建一个存储 TypedTuple 的集合 用于批量添加,也可以单独添加Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<>();tuples.add(new DefaultTypedTuple<>("P001", 0D));tuples.add(new DefaultTypedTuple<>("P002", 0D));tuples.add(new DefaultTypedTuple<>("P003", 0D));tuples.add(new DefaultTypedTuple<>("P004", 0D));tuples.add(new DefaultTypedTuple<>("P005", 0D));tuples.add(new DefaultTypedTuple<>("P006", 0D));Long add = redisTemplate.opsForZSet().add(cacheKey, tuples);System.out.println("初始化成功:"+ add);}/*** 添加排行榜数据*/@Testpublic void addRank() {redisTemplate.opsForZSet().incrementScore(cacheKey,"P002",7D);redisTemplate.opsForZSet().incrementScore(cacheKey,"P005",2D);redisTemplate.opsForZSet().incrementScore(cacheKey,"P006",9D);System.out.println("添加排行榜数据成功");}/*** 查询排行榜数据*/@Testpublic void queryRank() {// 查询排行榜全部数据按照分数从大到小排序Set<ZSetOperations.TypedTuple<Object>> set1 = redisTemplate.opsForZSet().reverseRangeWithScores(cacheKey, 0L, -1L);System.out.println("查询排行榜全部数据按照分数从大到小排序:");set1.forEach(tuple -> {System.out.println(tuple.getValue() + " : " + tuple.getScore());});// 查询排行榜销量前三的数据按照分数从大到小排序Set<ZSetOperations.TypedTuple<Object>> set2 = redisTemplate.opsForZSet().reverseRangeWithScores(cacheKey, 0L, 2L);System.out.println("查询排行榜销量前三的数据按照分数从大到小排序:");set2.forEach(tuple -> {System.out.println(tuple.getValue() + " : " + tuple.getScore());});// 查询排行榜销量大于等于1的数据从小到大排序,并且进行分页,每页2条数据查询第1页Set<ZSetOperations.TypedTuple<Object>> set3 = redisTemplate.opsForZSet().rangeByScoreWithScores(cacheKey, 1D, Double.MAX_VALUE, 0L, 2L);System.out.println("查询排行榜销量大于等于1的数据从小到大排序,并且进行分页,每页2条数据查询第1页:");set3.forEach(tuple -> {System.out.println(tuple.getValue() + " : " + tuple.getScore());});}
}

查询结果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/185574.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VirtualBox上安装CentOS7

基础环境&#xff1a;宿主机是64位Windows10操作系统&#xff0c;通过无线网访问网络。 macOS可以以类似方式进行安装&#xff0c;不同之处见最后补充。 Step1 安装VirtualBox VirtualBox是一款免费、开源、高性能的虚拟机软件&#xff0c;可以跨平台运行&#xff0c;支持Wi…

【神印王座】永恒之塔秘密透露,林鑫告白李馨,皓晨采儿甜蜜接吻

Hello,小伙伴们&#xff0c;我是拾荒君。 《神印王座》第83集如期而至&#xff0c;带来了令人期待已久的更新。与众多热情的观众一样&#xff0c;拾荒君一得到更新消息&#xff0c;便急不可耐地观赏起来。这一集中&#xff0c;龙皓晨随着月魔宫的月夜商队成功抵达联盟&#xf…

C++: string的模拟实现

C: string的模拟实现 一.前置说明1.模拟实现string容器的目的2.我们要实现的大致框架 二.默认成员函数1.构造函数2.拷贝构造函数1.传统写法2.现代写法 3.析构函数4.赋值运算符重载1.传统写法2.现代写法 三.遍历和访问1.operator[]运算符重载2.iterator迭代器 四.容量相关函数1.…

ssm+vue的公司安全生产考试系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的公司安全生产考试系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结…

探索前端设计的新境界——介绍IVueUI工具助力Vue页面设计

在快速发展的前端领域&#xff0c;Vue.js作为一款渐进式JavaScript框架&#xff0c;一直备受开发者喜爱。然而&#xff0c;在Vue前端开发的旅程中&#xff0c;页面设计常常是一个不可避免的挑战。今天&#xff0c;我要向大家介绍一款令Vue前端开发者受益匪浅的工具——www.ivue…

Python文件操作

目录 一.文件的编码二.文件的读取三.文件的写入四.文件的追加五.文件操作综合案例 一.文件的编码 编码就是一种规则集合&#xff0c;记录了内容和二进制进行相互转换的逻辑。最常见的是UTF-8编码计算机只认识0和1&#xff0c;所以需要将内容翻译成0和1才能保存在计算机中。同时…

“大+小模型”赋能油气行业高质量发展

近日&#xff0c;中国石油石化科技创新大会暨新技术成果展在北京盛大举行&#xff0c;九章云极DataCanvas公司携油气行业一站式AI综合解决方案重磅亮相&#xff0c;充分展示了公司助推油气行业实现AI规模化应用深厚的AI技术实力和领先的AI应用水准&#xff0c;赢得了行业专家和…

spring boot整合Jasypt实现配置加密

文章目录 目录 文章目录 前言 一、Jasypt是什么&#xff1f; 二、使用步骤 1.引入 2.测试使用 3.结果 总结 前言 一、Jasypt是什么&#xff1f; Jasypt&#xff08;Java Simplified Encryption&#xff09;是一个Java库&#xff0c;提供了一种简单的加密解密方式&#xff0c…

热门话题解析:pytest测试用例顺序问题解决方案!

前言 上一篇文章我们讲了在pytest中测试用例的命名规则&#xff0c;那么在pytest中又是以怎样的顺序执行测试用例的呢&#xff1f; 在unittest框架中&#xff0c;默认按照ACSII码的顺序加载测试用例并执行&#xff0c;顺序为&#xff1a;09、AZ、a~z&#xff0c;测试目录、测…

Codeforces Round 906 (Div. 2)(D推公式 E1分类讨论区间 E2 dp+线段树)

A - Doremys Paint 3 推公式得 b1b3b5b7.... b2b4b6b8... 所以如果只有一个数或者两个数且数量差小于等于1即可 #include<bits/stdc.h> using namespace std; const int N 2e510,mod1000003; #define int long long typedef long long LL; typedef pair<int, in…

第三方实验室LIMS管理系统源码,asp.net LIMS源码

LIMS实验室信息管理系统源码 LIMS系统的功能根据实验室的规模和任务而有所不同&#xff0c;其系统主要功能包括:系统维护、基础数据编码管理&#xff0c;样品管理、数据管理、报告管理、报表打印、实验材料管理、设备管理等。它可以取代传统的手工管理模式而给检测实验室带来巨…

java获取第n次出现字符串前后面字符串,如:截取第二个逗号后面的数据

java获取第n次出现字符串前后面字符串&#xff0c;如&#xff1a;截取第二个逗号后面的数据 方法&#xff1a; /*** 获取指定第几位字符串后面字符串&#xff0c;如&#xff1a;截取第二个逗号后面的数据** param str:要处理的字符串* param mediumStr&#xff1a;根据截取的媒…

时间序列异常检测14篇顶会论文合集,附必备工具和数据集

今天来聊聊一个在量化交易、网络安全检测、自动驾驶汽车和大型工业设备的日常维护等领域都有重要作用的研究主题&#xff1a;时间序列异常检测。 时间序列异常检测是一种在时间序列数据中识别和标识与预期模式、趋势或行为不符的异常点或事件的技术。鉴于它如此广泛的应用范围…

18、串口通信

串口介绍 串口是一种应用十分广泛的通讯接口&#xff0c;串口成本低、容易使用、通信线路简单&#xff0c;可实现两个设备的互相通信。 单片机的串口可以使单片机与单片机&#xff0c;单片机与电脑、单片机与各式各样的模块互相通信&#xff0c;极大的扩展了单片机的应用范围&…

MySQL InnoDB Cluster

MySQL InnoDB Cluster 一、InnoDB Cluster 基本概述 MySQL InnoDB Cluster 为 MySQL 提供了一个完整的高可用解决方案。通过使用 MySQL Shell 提供的 AdminAPI,你可以轻松地配置和管理一组至少由3个MySQL服务器实例组成的 InnoDB 集群。 InnoDB 集群中的每个 MySQL 服务器实例…

JRT和检验共用的打印层实现

之前对接的打印和导出是C#实现的&#xff0c;如果要完全Java化就需要用Java把打印元素绘制协议用Java实现&#xff0c;这次介绍实现主体搭建&#xff0c;最终使JRT达到完全信创和跨平台目标。到这篇后&#xff0c;所有的Java难题都解决完毕&#xff0c;几天到几周之内就可以把打…

(二进制、八进制、十进制、十六进制)的进制转换

整型有4种进制形式&#xff1a; 1.十进制&#xff1a; 都是以0-9这九个数字组成&#xff0c;不能以0开头。 2.二进制&#xff1a; 由0和1两个数字组成。 3.八进制&#xff1a; 由0-7数字组成&#xff0c;为了区分与其他进制的数字区别&#xff0c;开头都是以0开始。 4.十六进制…

聚类算法的算法原理

聚类算法是机器学习中常用的一种无监督学习方法&#xff0c;其主要目标是将数据集划分为具有相似特征的组或簇。这种算法在数据挖掘、模式识别、社交网络分析等领域有着广泛的应用。聚类算法的核心思想是通过计算数据点之间的相似度或距离&#xff0c;将相似的数据点聚集在一起…

WordPress 粘贴图片上传插件

找了很久&#xff0c;发现一款不错的插件&#xff0c;允许我们直接粘贴图片文件并且上传到媒体库。以前的插件上传后媒体库不会显示&#xff0c;这个要显示。 启用后编辑器会有一个图标&#xff0c;如果开启&#xff0c;那么久可以截图后直接粘贴了。 学习资料源代码&#xf…

TR转发路由器测评—云企业网实现跨地域跨VPC的网络互通测评实战【阿里云产品测评】

文章目录 一.转发路由器 Transit Router 测评1.1 准备阶段1.2 本文测评收获1.3 什么是云企业网实例、转发路由器实例和云数据传输服务 二.使用云企业网实现跨地域跨VPC的网络互通2.2 **测试连通性**2.3 网络拓扑如下&#xff1a; 心得&#xff1a;总结&#xff1a; 声明&#x…