【Redis从头学-8】Redis中的ZSet数据类型实战场景之用户积分榜
🧑💻作者名称:DaenCode
🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。
😎人生感悟:尝尽人生百味,方知世间冷暖。
📖所属专栏:Redis从头学
文章目录
- 🌟前言
- 🌟ZSet数据类型分析
- 🌟ZSet类型实战应用场景
- 用户积分榜功能
- 代码示例
- 数据测试
- 运行结果
- 🌟写在最后
🌟前言
之前的篇章对Redis的String、List、Hash、Set数据类型已经做出了具体分析,并举例说明了其具体的实战场景。本文就结合Zset数据类型结构的特性,一起探讨其实战中的应用场景,并以积分榜功能为例来展示Zset数据类型的特点。
🌟ZSet数据类型分析
Redis中的ZSet(有序集合)数据类型是一种有序且不重复的集合
,它在Set的基础上增加了一个分数(score)字段,用于对集合中的元素进行排序。下面对Redis ZSet数据类型进行一些分析:
- 有序性:ZSet中的元素按照其分数进行排序,使得元素在集合中有序存储。每个元素都有一个唯一的分数,可用于根据指定顺序进行范围查询或排序。
- 元素的唯一性:和Set一样,ZSet保证其中的元素都是唯一的,不会存在重复的元素。
- 高效的添加、删除和更新操作:ZSet提供了O(log N)时间复杂度的添加、删除和更新元素的操作。其中N为ZSet中元素的数量。这归功于Redis内部使用了跳表(Skip List)和哈希表两种结构实现ZSet。
- 支持范围查询和排名操作:ZSet支持根据分数范围进行查询,并可以按照分数大小对元素进行排名。通过排名操作,可以获取元素的排名以及根据排名返回一定范围的元素。
🌟ZSet类型实战应用场景
ZSet常用于需要根据分数进行排序的场景,例如排行榜、计分系统、有序任务队列
等。它能够快速获取按照分数排序的元素,并且支持动态更新分数。
总而言之,Redis的ZSet数据类型提供了有序、唯一且高效的集合操作
。它在排行榜、计分系统以及需要有序处理任务队列等场景中非常有用。通过对元素进行分数的设置和操作,可以灵活地满足各种实时数据排序和查询
的需求。
用户积分榜功能
代码示例
我们使用了Spring Data Redis提供的RedisTemplate来操作Redis的ZSet。通过@Resource注解将RedisTemplate注入到LeaderboardService类中。
在LeaderboardService中,我们定义很多的功能方法来实现用户积分榜的功能,如添加用户积分、增加用户积分、获取用户排名、获取用户积分、获取排名靠前的用户列表以及获取积分在指定范围内的用户列表。
@Component
public class LeaderboardService {private static final String LEADERBOARD_KEY = "leaderboard";@Resourceprivate RedisTemplate<String, String> redisTemplate;/*** 添加用户积分** @param user 用户名* @param score 积分*/public void addScore(String user, double score) {ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();zSetOperations.add(LEADERBOARD_KEY, user, score);}/*** 增加用户积分** @param user 用户名* @param score 积分增加量*/public void incrementScore(String user, double score) {ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();zSetOperations.incrementScore(LEADERBOARD_KEY, user, score);}/*** 获取用户排名(从高到低)** @param user 用户名* @return 用户的排名,如果用户不存在,则返回null*/public Long getUserRank(String user) {ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();return zSetOperations.reverseRank(LEADERBOARD_KEY, user);}/*** 获取用户积分** @param user 用户名* @return 用户的积分,如果用户不存在,则返回null*/public Double getUserScore(String user) {ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();return zSetOperations.score(LEADERBOARD_KEY, user);}/*** 获取排名靠前的用户列表** @param count 列表数量* @return 排名靠前的用户列表*/public Set<String> getTopUsers(int count) {ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();Set<String> topUsers = zSetOperations.reverseRange(LEADERBOARD_KEY, 0, count - 1);return topUsers;}/*** 获取积分在指定范围内的用户列表** @param minScore 最低积分* @param maxScore 最高积分* @return 积分在指定范围内的用户列表*/public Set<String> getUsersInRange(double minScore, double maxScore) {ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();Set<String> usersInRange = zSetOperations.rangeByScore(LEADERBOARD_KEY, minScore, maxScore);return usersInRange;}/*** 获取积分在指定范围内的用户列表,并返回用户及其对应的积分信息** @param minScore 最低积分* @param maxScore 最高积分* @return 包含用户及其对应积分的用户列表*/public Set<String> getUsersWithScoresInRange(double minScore, double maxScore) {ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();Set<ZSetOperations.TypedTuple<String>> usersWithScoresInRange = zSetOperations.rangeByScoreWithScores(LEADERBOARD_KEY, minScore, maxScore);// 将TypedTuple转换为只包含用户的SetSet<String> usersSet = usersWithScoresInRange.stream().map(ZSetOperations.TypedTuple::getValue).collect(Collectors.toSet());return usersSet;}}
数据测试
使用了 Spring Boot 框架来启动应用程序,并通过上下文获取 LeaderboardService 类的实例。然后,我们按照需求调用 LeaderboardService 类中的方法。
@SpringBootApplication
public class Application {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);LeaderboardService leaderboardService = context.getBean(LeaderboardService.class);// 添加用户积分leaderboardService.addScore("User1", 100);leaderboardService.addScore("User2", 200);leaderboardService.addScore("User3", 300);leaderboardService.addScore("User4", 400);leaderboardService.addScore("User5", 500);// 增加用户积分leaderboardService.incrementScore("User1", 50);leaderboardService.incrementScore("User3", 150);// 获取用户排名Long user1Rank = leaderboardService.getUserRank("User1");System.out.println("User1 Rank: " + user1Rank);// 获取用户积分Double user3Score = leaderboardService.getUserScore("User3");System.out.println("User3 Score: " + user3Score);// 获取排名靠前的用户列表Set<String> topUsers = leaderboardService.getTopUsers(3);System.out.println("Top Users: " + topUsers);// 获取积分在指定范围内的用户列表Set<String> usersInRange = leaderboardService.getUsersInRange(200, 400);System.out.println("Users in Range: " + usersInRange);// 获取积分在指定范围内的用户列表,并返回用户及其对应的积分信息Set<String> usersWithScoresInRange = leaderboardService.getUsersWithScoresInRange(200, 400);System.out.println("Users with Scores in Range: " + usersWithScoresInRange);}
}
运行结果
User1 Rank: 4
User3 Score: 450.0
Top Users: [User5, User4, User3]
Users in Range: [User4, User3, User2]
Users with Scores in Range: [User4, User3]
🌟写在最后
有关于Redis中的ZSet数据类型实战应用场景到此就结束了。功能演示代码的逻辑简单,目的是理解ZSet数据类型的应用,实际场景的逻辑根据具体需求而定。感谢大家的阅读,希望大家在评论区对此部分内容散发讨论或者有什么其他场景也可以在评论区提出。
相关文章:

【Redis从头学-8】Redis中的ZSet数据类型实战场景之用户积分榜
🧑💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:Re…...
Springboot内嵌SQLite配置使用
版本号 MacOS Apple M1 | Jdk17 | Maven 3.8.5 | SpringBoot 2.6.9 | SQLite 3.42.0.0 pom.xml <dependencies><dependency><groupId>org.xerial</groupId><artifactId>sqlite-jdbc</artifactId><version>3.42.0.0</version&g…...

【微服务学习笔记】认识微服务
【微服务学习笔记】认识微服务 单体架构 分布式架构 微服务架构 SpringCloud 服务拆分和注意事项 服务拆分的案例demo 各个服务之间的数据库都是相互独立的,你不能直接访问对方的数据库,只能从一个服务像另外一个服务发起远程调用 在订单模块的服务中 …...
基于Android R快速编译recovery-ramdisk.img
Android默认没有单编recovery-ramdisk.img的命令,我们可以自己修改Makefile实现 修改:build/core/Makefile 添加: .PHONY: recovery-ramdisk-nodeps recovery-ramdisk-nodeps: $(MKBOOTFS) | $(COMPRESSION_COMMAND_DEPS)echo "make …...

Redis分布式缓存
分布式缓存 -- 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题: 1.Redis持久化 Redis有两种持久化方案: RDB持久化 AOF持久化 1.1.RDB持久化 RDB全称Redis Database Backup file(Redis数据备份文件)&#x…...
最大公约数和最小公倍数
最大公约数: 概念: 公约数中最大的称为最大公约数。 对任意的若干个正整数,1总是它们的公因数。 公约数与公倍数相反,就是既是A的约数同时也是B的约数的数,12和15的公约数有1,3,最大公约数就是…...

数据结构——二叉搜索树(附带C++实现版本)
文章目录 二叉搜索树概念 二叉树的实际应用二叉树模拟实现存储结构二叉搜索树构成二叉搜索树的查找插入操作中序遍历二叉树的删除循环(利用左子树最右节点)递归(利用右子树根节点) 二叉树拷贝二叉树资源的销毁 二叉树实现完整代码总结 二叉搜索树 概念 二叉搜索树…...
C++(3)C++对C的扩展Extension
类型增强 1、类型更加严格 不初始化,无法通过编译;C不初始化,则随机赋值 #include <iostream> #include <stdlib.h>int main() {const int a 100; //真正的const,无法修改 // int *p &a; 报错const int *p…...
在vscode(idea)使用GitHub账号、Copilot异常
在idea使用GitHub账号、Copilot异常 登录GitHub显示 Invalid authentication data.Connection refused: connect或者副驾驶显示 Failed to initiate the GitHub login process. Please try again.一般网上的方法推荐使用token登录,或者降级副驾驶 经过研究&#x…...

新的后端渲染:服务器驱动UI
通过API发送UI是一种彻底的新方法,将改变传统的UI开发。 一项正在改变我们对用户界面 (UI) 的看法的技术是通过 API 发送 UI,也称为服务器驱动UI。这种方法提供了新水平的活力和灵活性,正在改变 UI 开发的传统范例。 服务器驱动 UI 不仅仅是…...

Postman如何做接口自动化测试?
前言 什么是自动化测试 把人对软件的测试行为转化为由机器执行测试行为的一种实践。 例如GUI自动化测试,模拟人去操作软件界面,把人从简单重复的劳动中解放出来。 本质是用代码去测试另一段代码,属于一种软件开发工作,已经开发完…...

excel文本函数篇2
本期主要介绍LEN、FIND、SEARCH以及后面加B的情况: (1)后缀没有B:一个字节代表一个中文字符 (2)后缀有B:两个字节代表一个中文字符 1、LEN(text):返回文本字符串中的字符个数 2、…...

【MyBatis】动态SQL > 重点:${...}和#{...}与resultMap和resultType的区别
目录 一、MyBatis动态sql 1.1 动态sql的作用 1.2 动态sql作用论证 1.2.1 条件判断:<if> 1.2.2 循环迭代:<foreach> 1.2.3 SQL片段重用 1.2.4 动态条件组合:<choose><when><otherwise> 1.2.5 <where…...

什么是BEM命名规范?为什么要使用BEM命名规范?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ BEM命名规范⭐ 为什么使用BEM命名规范?⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为…...

JavaScript:交集和差集的应用场景
在集合A和集合B中,属于集合A,同时也属于集合B的元素组成的集合,就是交集。 在A中所有不属于集合B元素,组合成集合,就是差集。 那么在平时的开发中,如何使用差集和交集来解决问题呢? 现在有这…...

达梦数据库表空间创建和管理
概述 本文将介绍在达梦数据库如何创建和管理表空间。 1.创建表空间 1.1表空间个数限制 理论上最多允许有65535个表空间,但用户允许创建的表空间 ID 取值范围为0~32767, 超过 32767 的只允许系统使用,ID 由系统自动分配,ID不能…...

三、MySQL 数据库安装集
一、CentOS—YUM 1. MySQL—卸载 # 1、查看存在的MySQL。 rpm -qa | grep -i mysql rpm -qa | grep mysql# 2、删除存在的MySQL。 rpm -e –-nodeps 包名# 3、查找存在的MySQL目录。 find / -name mysql# 4、删除存在的MySQL目录。 rm -rf 目录# 5、删除存在的MySQL配置文件。…...

【BASH】回顾与知识点梳理(三十九)
【BASH】回顾与知识点梳理 三十九 三十九. make、tarball、函数库及软件校验39.1 用 make 进行宏编译为什么要用 makemakefile 的基本语法与变量 39.2 Tarball 的管理与建议使用原始码管理软件所需要的基础软件Tarball 安装的基本步骤一般 Tarball 软件安装的建议事项 (如何移除…...

蓝蓝设计-UI设计公司案例-HMI列车监控系统界面设计解决方案
2013年,为加拿大庞巴迪(Bombardier)设计列车监控系统界面设计。 2015-至今,为中车集团旗下若干公司提供HMI列车监控系统界面设计,综合考虑中车特点、城轨车、动车组的不同需求以及HMI硬键屏和触摸 屏的不同操作方式,重构框架设计、交互设计、…...

Blazor前后端框架Known-V1.2.13
V1.2.13 Known是基于C#和Blazor开发的前后端分离快速开发框架,开箱即用,跨平台,一处代码,多处运行。 Gitee: https://gitee.com/known/KnownGithub:https://github.com/known/Known 概述 基于C#和Blazo…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...