当前位置: 首页 > news >正文

Redis 有序集合【实现排行榜】

使用 Redis 的 Sorted Set 数据结构可以非常高效地实现实时排行榜功能。Sorted Set 允许将元素按分数进行排序,同时支持插入、删除和查询操作,且这些操作的时间复杂度较低,非常适合处理高并发的场景。

实现思路

  • 插入操作:当用户产生分数时,将用户 ID 和分数插入到 Redis 的 Sorted Set 中。
  • 查询操作:根据用户分数在排行榜中的位置,获取某个用户的排名或获取前 N 名的用户列表。

1. 创建排行榜表结构

首先,在 MySQL 中创建一个存储用户和分数的表,以便持久化保存数据

CREATE TABLE user_scores (user_id INT PRIMARY KEY,score INT NOT NULL
);

2. 插入分数到排行榜

当用户获得分数时,将用户 ID 和分数插入到 Redis 的 Sorted Set 中。

<?php
function addScoreToLeaderboard($userId, $score) {$redis = new Redis();$redis->connect('127.0.0.1', 6379);// 将用户ID和分数插入到Sorted Set中$redis->zAdd('leaderboard', $score, $userId);// 更新MySQL中的持久化数据$db = new mysqli('localhost', 'username', 'password', 'database');$stmt = $db->prepare("INSERT INTO user_scores (user_id, score) VALUES (?, ?) ON DUPLICATE KEY UPDATE score = ?");$stmt->bind_param("iii", $userId, $score, $score);$stmt->execute();
}// 示例:将用户123的分数更新为500
addScoreToLeaderboard(123, 500);

3. 查询用户的排名

根据用户的分数,查询其在排行榜中的排名。Redis 的 zRevRank 命令返回的是从高到低的排名。

<?php
function getUserRank($userId) {$redis = new Redis();$redis->connect('127.0.0.1', 6379);// 获取用户的排名(Redis 的排名从0开始,所以加1)$rank = $redis->zRevRank('leaderboard', $userId);return $rank !== false ? $rank + 1 : null;
}// 示例:获取用户123的排名
$rank = getUserRank(123);
echo "User 123's rank: " . $rank . "\n";

4. 获取排行榜前 N 名

通过 Redis 的 zRevRange 命令获取排行榜前 N 名的用户。

<?php
function getTopNUsers($n) {$redis = new Redis();$redis->connect('127.0.0.1', 6379);// 获取前N名用户ID及其分数$topUsers = $redis->zRevRange('leaderboard', 0, $n - 1, true);return $topUsers;
}// 示例:获取排行榜前10名
$topUsers = getTopNUsers(10);
print_r($topUsers);

5. 更新分数和排名

如果用户的分数需要更新,可以直接通过 zAdd 命令更新 Redis 中的分数,排行榜会自动调整顺序。

<?php
function updateScore($userId, $newScore) {$redis = new Redis();$redis->connect('127.0.0.1', 6379);// 更新用户的分数$redis->zAdd('leaderboard', $newScore, $userId);// 更新MySQL中的持久化数据$db = new mysqli('localhost', 'username', 'password', 'database');$stmt = $db->prepare("UPDATE user_scores SET score = ? WHERE user_id = ?");$stmt->bind_param("ii", $newScore, $userId);$stmt->execute();
}// 示例:更新用户123的分数为600
updateScore(123, 600);

6. 实时排行榜特性

Redis 的 Sorted Set 能够以 O(log(N)) 的时间复杂度完成插入和删除操作,以 O(log(N) + M) 的时间复杂度完成范围操作(M 是范围内元素的数量)。这种特性使得它非常适合用于高并发环境下的排行榜应用。

7. 扩展功能

  • 分页查询:使用 zRevRange 结合起始和结束索引可以实现分页获取排行榜用户。
  • 批量插入:如果有多个用户需要同时插入或更新分数,可以使用 Redis 的管道(pipeline)机制,提高操作效率。
  • 持久化管理:定期将 Redis 中的数据同步回 MySQL,以防止数据丢失。

总结

通过 Redis 的 Sorted Set 实现实时排行榜,不仅操作简单、效率高,而且非常适合处理高并发的场景。将用户的分数与排名存储在 Redis 中,结合 MySQL 进行数据的持久化存储,可以在保证性能的同时确保数据的可靠性。

 

相关文章:

Redis 有序集合【实现排行榜】

使用 Redis 的 Sorted Set 数据结构可以非常高效地实现实时排行榜功能。Sorted Set 允许将元素按分数进行排序&#xff0c;同时支持插入、删除和查询操作&#xff0c;且这些操作的时间复杂度较低&#xff0c;非常适合处理高并发的场景。 实现思路 插入操作&#xff1a;当用户…...

ORACLE数据库管理系统介绍

1.ORACLE的特点: 可移植性 ORACLE采用C语言开发而成,故产品与硬件和操作系统具有很强的独立性。从大型机到微机上都可运行ORACLE的产品。可在UNIX、DOS、Windows等操作系统上运行。可兼容性 由于采用了国际标准的数据查询语言SQL,与IBM的SQL/DS、DB2等均兼容。并提供读取其它…...

C# 中Linq探讨 Or条件拼接

在C#中&#xff0c;没有直接内置于.NET Core或.NET Framework中的NuGet包能够直接“拼接”LINQ的OR条件&#xff0c;因为LINQ本身设计为一种声明式编程模型&#xff0c;用于查询数据集合。然而&#xff0c;你可以通过一些方式来实现多个条件以OR逻辑组合的效果&#xff0c;而不…...

有关应用层面试题有关库的思维导体

面试题目&#xff1a; TCP通信中3次握手和四次挥手&#xff1f; 答&#xff1a; 第一次握手&#xff1a;客户端发送SYN包&#xff08;SYN1, seq0&#xff09;给服务器&#xff0c;并进入SYN_SENT状态&#xff0c;等待服务器返回确认包。第二次握手&#xff1a;服务器接收到S…...

记一次 SAP BP 编号范围错误引发的一个问题 GET_NRIV_LINE

本来想着循着错误提示去排查&#xff0c;但是还是想看看业务发生了什么&#xff0c;他们的操作是否有问题&#xff0c;不经意间发现 号码段是有问题的&#xff0c;由此大概可以判断是他们编号范围和类型之间的问题 角色和分组是否一致的&#xff0c;如果不一致就发生了以上错误…...

(17)ELK大型储存库的搭建

前言&#xff1a; els是大型数据储存体系&#xff0c;类似于一种分片式存储方式。elasticsearch有强大的查询功能&#xff0c;基于java开发的工具&#xff0c;结合logstash收集工具&#xff0c;收集数据。kibana图形化展示数据&#xff0c;可以很好在大量的消息中准确的找到符…...

每日一问:Kafka消息丢失与堆积问题分析(简化版)

Kafka 消息系统问题解析 在本篇博客中&#xff0c;我们将深入探讨 Kafka 中常见的两大问题&#xff1a;消息丢失和消息堆积。首先&#xff0c;我们将简要介绍 Kafka 的基本工作原理&#xff0c;随后分别分析消息丢失和堆积的原因&#xff0c;并提供针对性的解决方案。 关于其详…...

C语言中函数sizeof和strlen区别

sizeof和strlen是C语言中的两个常用函数&#xff0c;它们的作用和使用方式有所不同。 sizeof sizeof是一个运算符而非函数&#xff0c;用于计算数据类型或变量占用的字节数。它可以计算任意数据类型&#xff08;包括基本类型、自定义结构体、数组等&#xff09;的大小。例如&…...

RAG与LLM原理及实践(14)---- Python + MinIO + Kafka进阶

目录 背景 根因分析 配置 构造 创建 network 构造 zookeeper 构造 kafka 参数构造 原理解析 图解 全过程解析 工具使用 kafkacat 查看 broker python 实现 python send + kafka recv python 代码 kafka recv 运行效果 python recv + kafka send python 代…...

接口自动化-代码实现

接口自动化基础 1、接口自动化测试 接口自动化&#xff1a;使用工具或代码代替人对接口进行测试的技术测试目的&#xff1a; 防止开发修改代码时引入新的问题测试时机&#xff1a; 开发进行系统测试转测前&#xff0c;可以先进行接口自动化脚本的编写开发进行系统测试转测后&…...

如何查看linux大文件

文章目录 一、查看存储情况二、查看指定路径下的文件大小查看临时文件和日志的大小 三、查找home目录下文件大小大于100M的大文件四、查看INNODE使用情况五、查看进程使用情况查看所有进程查看特定进程杀死相关进程 六、清除缓存操作七、 查看docker的硬盘占用情况详细查看 一、…...

生成式人工智能服务大模型备案答疑

问&#xff1a;大模型备案范围 答&#xff1a;利用生成式人工智能技术向中华人民共和国境内公众提供生成文本、图片、音频、视频等内容的服务&#xff0c;适用本办法。 未向境内公众提供生成式人工智能服务的&#xff0c;不适用本办法的规定。 ps&#xff1a;生成式人工智能…...

QT-贪吃蛇小游戏

QT-贪吃蛇小游戏 一、演示效果二、核心代码三、下载链接 一、演示效果 二、核心代码 #include "Food.h" #include <QTime> #include <time.h> #include "Snake.h"Food::Food(int foodSize):foodSize(foodSize) {coordinate.x -1;coordinate.…...

虚幻5|AI视力系统,听力系统,预测系统(1)视力系统

继宠物伴随系统初步篇后续 虚幻5|AI巡逻宠物伴随及定点巡逻—初步篇-CSDN博客 一&#xff0c;听力系统 1.打开宠物ai的角色蓝图 2.选中ai感知组件 右侧细节&#xff0c;找到ai感知&#xff0c;添加感知配置&#xff0c;我们需要的是ai视力配置 3.选中左侧创建的ai感知组件&…...

IC rankIC

IC IC衡量的是预测值和实际值之间的相关系数 计算公式为&#xff1a;IC Pearson(R(predicted),R(actual)) 取值范围&#xff1a;[-1, 1]&#xff0c;其中1表示完全相关&#xff0c;也就是预测值和实际值完全一样。0表示完全不相关&#xff0c;-1表示&#xff0c;反向相关 ra…...

Windows服务器IIS7下如何查看真实报错原因

背景 IIS7默认为友好报错&#xff0c;或只报错代码。如500错误&#xff0c;401错误等。根据这些错误无法定位真实原因&#xff0c;故而需要显示真实的错误信息。 解决方案 以500错误为例说明。 1、打开IIS,点全局设置中的"错误页"(注意必须是全局网站)。 2、右击50…...

深度学习设计模式之策略模式

文章目录 前言一、介绍二、特点三、详细介绍1.核心组成2.代码示例3.优缺点优点缺点 4.使用场景 总结 前言 策略模式定义一系列算法&#xff0c;封装每个算法&#xff0c;并使它们可以互换。 一、介绍 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&…...

Linux 下安装miniconda(少走弯路)

Miniconda 和 Conda 都是用于管理 Python&#xff08;及其他语言&#xff09;环境和包的工具。 conda对于我来说是太臃肿了&#xff0c;很多的包我不会使用&#xff0c;所以选择安装miniconda是一个较好的选择。 下面是linux安装miniconda的实际操作。 在以下的网站&#xf…...

java ssl使用自定义证书

1.证书错误 Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 2.生成客户端证书 openssl x509 -in <(openssl s_client -connect 192.168.11.19:8101 -prexit 2>/dev/null) -ou…...

【ARM+Codesys 客户案例 】基于RK3568/A40i/STM32+CODESYS开发的控制器在自动输送分拣系统上的应用,支持定制

2021年“京东618” 累计下单金额超3438亿元,再次刷新纪录! 从下单到收货&#xff0c;各种货品均可在短短几天内通过四通八达的物流网络送达全国任何一个家庭。电子商务和快递物流的迅猛发展对仓储、分拣、配送效率和准确性均提出了更高的要求&#xff0c;加速了智能物流的发展。…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

Python训练营-Day26-函数专题1:函数定义与参数

题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一个名为 calculate_circle_area 的函数&#xff0c;该函数接收圆的半径 radius 作为参数&#xff0c;并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求&#xff1a;函数接收一个位置参数 radi…...