【Redis从头学-8】Redis中的ZSet数据类型实战场景之用户积分榜

🧑‍💻作者名称:DaenCode
🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。
😎人生感悟:尝尽人生百味,方知世间冷暖。
📖所属专栏:Redis从头学


在这里插入图片描述


文章目录

  • 🌟前言
  • 🌟ZSet数据类型分析
  • 🌟ZSet类型实战应用场景
    • 用户积分榜功能
      • 代码示例
      • 数据测试
      • 运行结果
  • 🌟写在最后

🌟前言

之前的篇章对Redis的String、List、Hash、Set数据类型已经做出了具体分析,并举例说明了其具体的实战场景。本文就结合Zset数据类型结构的特性,一起探讨其实战中的应用场景,并以积分榜功能为例来展示Zset数据类型的特点。

🌟ZSet数据类型分析

Redis中的ZSet(有序集合)数据类型是一种有序且不重复的集合,它在Set的基础上增加了一个分数(score)字段,用于对集合中的元素进行排序。下面对Redis ZSet数据类型进行一些分析:

  1. 有序性:ZSet中的元素按照其分数进行排序,使得元素在集合中有序存储。每个元素都有一个唯一的分数,可用于根据指定顺序进行范围查询或排序。
  2. 元素的唯一性:和Set一样,ZSet保证其中的元素都是唯一的,不会存在重复的元素。
  3. 高效的添加、删除和更新操作:ZSet提供了O(log N)时间复杂度的添加、删除和更新元素的操作。其中N为ZSet中元素的数量。这归功于Redis内部使用了跳表(Skip List)和哈希表两种结构实现ZSet。
  4. 支持范围查询和排名操作: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数据类型的应用,实际场景的逻辑根据具体需求而定。感谢大家的阅读,希望大家在评论区对此部分内容散发讨论或者有什么其他场景也可以在评论区提出。


请添加图片描述

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

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

相关文章

回流焊炉温曲线图讲解

从下面回流焊炉温曲线标准图分析回流焊的原理&#xff1a; 当PCB进入升温区&#xff08;干燥区&#xff09;时&#xff0c;焊锡膏中的溶剂、气体蒸发掉&#xff0c;同时焊锡膏中的助焊剂润湿焊盘、元器件端头和引脚&#xff0c;焊锡膏软化、塌落、覆盖了焊盘&#xff0c;将焊盘…

部署FTP服务(二)

目录 2.访问FTP服务 1.使用ftp命令行工具 2.使用浏览器 3.使用FileZilla Client 3.Serv-U 1.定义新域 2.创建用户 4. windowsserver搭建ftp服务器 一、FTP工具 二、Windows资源管理器 三、IE浏览器访问 2.访问FTP服务 下面在一台装有Windows10操作系统的计算机中&#…

长胜证券:九成注册制公司选择上市标准一,牛股“双高”特征明显

新股注册制施行以来&#xff0c;新股公司可选的上市规范愈加多样化&#xff0c;不同板块、不同上市规范的新股公司亦呈现出不同特征&#xff0c;新股上市后不再呈现“套路化”的上涨行情&#xff0c;新股破发成为常态。数据显现&#xff0c;2022年全年及2023年以来&#xff0c;…

中小企业精细化仓库管理,WMS仓储管理系统必不可少

尽管传统中小企业的仓库管理并不需要建立大型全自动立体智能仓库&#xff0c;但为了确保企业运营的稳定性和后备支持&#xff0c;它们仍然需要在管理方面制定更多的标准和规范。而为了达到这些目标&#xff0c;WMS仓储管理系统解决方案是必不可少的。 中小企业WMS仓储管理系统…

SpringBoot 模板模式实现优惠券逻辑

一、计算逻辑的类结构图 在这张图里&#xff0c;顶层接口 RuleTemplate 定义了 calculate 方法&#xff0c;抽象模板类 AbstractRuleTemplate 将通用的模板计算逻辑在 calculate 方法中实现&#xff0c;同时它还定义了一个抽象方法 calculateNewPrice 作为子类的扩展点。各个具…

适合国内用户的五款ChatGPT插件

众所周知使用ChatGPT3.5需要使用魔法且不稳定&#xff0c;订阅ChatGPT4.0每月需要支付20美元&#xff0c;并且使用次数有限制。对于那些不想每年花费240美元&#xff08;超过1500元人民币&#xff09;来使用GPT4.0的朋友们来说&#xff0c;还有别的办法吗&#xff1f; 答案是&…

【C语言】位段,枚举和联合体详解

目录 1.位段 1.1 什么是位段 1.2 位段的内存分配 1.3 位段的跨平台问题 2.枚举 2.1 枚举类型的定义 2.2 枚举的优点 3. 联合&#xff08;共用体&#xff09; 3.1 联合类型的定义 3.2 联合的特点 3.3 联合大小的计算 1.位段 1.1 什么是位段 位段的声明和结构体是类…

多线程——学习笔记 1

目录 多线程的了解多线程并行和并发的区别Java程序运行原理多线程程序实现的方式1.继承Thread2.实现Runnable 多线程(实现Runnable的原理&#xff09;实现多线程两种方式的区别匿名内部类实现线程的两种方式获取线程名字和设置名字获取当前线程的对象——hread.currentThread()…

Docker拉取并配置Grafana

Linux下安装Docker请参考&#xff1a;Linux安装Docker 安装准备 新建挂载目录 /opt/grafana/data目录&#xff0c;准备用来挂载放置grafana的数据 /opt/grafana/plugins目录&#xff0c;准备用来放置grafana的插件 /opt/grafana/config目录&#xff0c;准备用来挂载放置graf…

取模运算符在数组下标的应用

什么是取模运算符%&#xff1f; 定义&#xff1a; a mod b&#xff0c;设a、b属于正整数且b>0&#xff0c;如果q、r属于正整数满足aq*br&#xff0c;且0≤r<b&#xff0c;则定义&#xff1a; a mod b r 注意&#xff1a;取模运算符两侧的除数和被除数都是整数&#xff…

Debootstrap 教程

文章目录 Debootstrap 教程安装 debootstrap使用 debootstrap运行 debootstrap进入新的系统结束语 Debootstrap 教程 debootstrap 是一个用于在 Debian-based 系统上创建一个基本的 Debian 系统的工具。它可以用于创建 chroot 环境、容器或者为新的系统安装做准备。 安装 deb…

分布式数据库架构:高可用、高性能的数据存储

在现代信息时代&#xff0c;数据是企业发展的核心。为了支持海量数据的存储、高并发访问以及保证数据的可靠性&#xff0c;分布式数据库架构应运而生。分布式数据库架构是一种将数据存储在多个物理节点上&#xff0c;并通过一系列复杂的协调和管理机制来提供高可用性和高性能的…

Qt下拉菜单

1&#xff0c;QComboBox 2&#xff0c;setMenu()---设置下拉菜单 AI对话未来丨智能写作对话: setMenu()是QWidget类的一个成员函数&#xff0c;在Qt中用于将一个菜单作为一个控件的下拉菜单设置。具体来说&#xff0c;它会把相应的菜单对象与该控件关联&#xff0c;并在控件上…

Element通过v-for循环渲染的form表单校验

需求&#xff1a;有个表单信息是v-for渲染的&#xff0c;例如下图&#xff0c;通过循环遍历实现新增和删除模块&#xff0c;按照平时的写法实现校验&#xff0c;是不能实现我们想要的效果&#xff0c;根据这个需求&#xff0c;我找到了一个解决方法 1.HTML <el-form ref&qu…

ESD门禁管理系统的主要功能和优势

ESD门禁管理系统是一种用于控制和管理人员进出特定区域的系统。它通常由门禁控制器、门禁读卡器、门禁管理软件等组成。 ESD门禁管理系统的主要功能包括&#xff1a; 1. 门禁控制&#xff1a;通过门禁控制器实现对门禁设备的控制&#xff0c;如开关门、锁定门等。 2. 门禁验…

Go与Rust的对比与分析

Rust 和 Go 是两种现代语言&#xff0c;近年来获得了巨大的关注&#xff0c;每种语言都有自己独特的优势和权衡。在这篇文章中&#xff0c;我们将深入探讨 Rust 和 Go 之间的差异&#xff0c;重点关注性能、语言功能和其他关键因素&#xff0c;以帮助您针对您的开发需求做出明智…

【面试】项目经理面试题

文章目录 一、项目管理面试中通常会问到的问题1.项目管理软件工具知识2.做项目计划的技能3.人员管理技能4.沟通技巧5.方法论知识 二、问面试官的问题三. 面试系列推荐 一、项目管理面试中通常会问到的问题 1.项目管理软件工具知识 问题 1: 工期和工作量之间的差异是什么? 答案…

视频汇聚平台EasyCVR安防视频监控在地下停车场中的具体应用方案

一、背景 随着我国城市化进程的加快&#xff0c;汽车已成为人们生活中不可缺少的交通工具&#xff0c;但在许多城市中&#xff0c;买车容易&#xff0c;停车难的问题愈发突出。特别是在人群密集的商场、写字楼和地下停车场&#xff0c;车流量大、车况复杂。传统的人工判断方式耗…

5、Spring_DI注解开发

DI 注解开发 1.目前面临问题 建立 mapper public interface EmployeeMapper {void save(); }建立 mapper 实现类 Repository public class EmployeeMapperImpl implements EmployeeMapper {public void save(){System.out.println("保存员工信息");} }建立 service …

【Unity】如何制作小地图

我们为什么要制作小地图呢&#xff1f; 原因很简单&#xff1a; 导航和定位&#xff1a;小地图可以显示玩家当前位置以及周围环境的概览。这使得玩家能够更好地导航和定位自己在游戏中的位置&#xff0c;找到目标或避开障碍物。场景了解&#xff1a;通过小地图&#xff0c;玩…