使用Redis實(shí)現(xiàn)用戶積分排行榜的教程
排行榜功能是一個(gè)很普遍的需求。使用 Redis 中有序集合的特性來(lái)實(shí)現(xiàn)排行榜是又好又快的選擇。
一般排行榜都是有實(shí)效性的,比如“用戶積分榜”。如果沒(méi)有實(shí)效性一直按照總榜來(lái)排,可能榜首總是幾個(gè)老用戶,對(duì)于新用戶來(lái)說(shuō),那真是太令人沮喪了。
首先,來(lái)個(gè)“今日積分榜”吧,排序規(guī)則是今日用戶新增積分從多到少。
那么用戶增加積分時(shí),都操作一下記錄當(dāng)天積分增加的有序集合。
假設(shè)今天是 2015 年 04 月 01 日,UID 為 1 的用戶因?yàn)槟硞€(gè)操作,增加了 5 個(gè)積分。
Redis 命令如下:
ZINCRBY rank:20150401 5 1
假設(shè)還有其他幾個(gè)用戶也增加了積分:
ZINCRBY rank:20150401 1 2 ZINCRBY rank:20150401 10 3
看看現(xiàn)在有序集合 rank:20150401 中的數(shù)據(jù)(withscores 參數(shù)可以附帶獲取元素的 score):
ZRANGE rank:20150401 0 -1 withscores 1) "2" 2) "1" 3) "1" 4) "5" 5) "3" 6) "10"
按照分?jǐn)?shù)從高到低,獲取 top10:
ZREVRANGE rank:20150401 0 9 withscores 1) "3" 2) "10" 3) "1" 4) "5" 5) "2" 6) "1"
因?yàn)橹挥腥齻€(gè)元素,所以就查詢(xún)出了這些數(shù)據(jù)。
如果每天記錄當(dāng)天的積分排行榜,那么其他花樣百出的榜單也就簡(jiǎn)單了。
比如“昨日積分榜”:
ZREVRANGE rank:20150331 0 9 withscores
利用并集實(shí)現(xiàn)多天的積分總和,實(shí)現(xiàn)“上周積分榜”:
ZUNIONSTORE rank:last_week 7 rank:20150323 rank:20150324 rank:20150325 rank:20150326 rank:20150327 rank:20150328 rank:20150329 WEIGHTS 1 1 1 1 1 1 1
這樣就將 7 天的積分記錄合并到有序集合 rank:last_week 中了。權(quán)重因子 WEIGHTS 如果不給,默認(rèn)就是 1。為了不隱藏細(xì)節(jié),特意寫(xiě)出。
那么查詢(xún)上周積分榜 Top10 的信息就是:
ZREVRANGE rank:last_week 0 9 withscores
“月度榜”、“季度榜”、“年度榜”等等就以此類(lèi)推。
下面給出一個(gè) PHP 版的簡(jiǎn)單實(shí)現(xiàn)。使用 Redis 依賴(lài)于 PHP 擴(kuò)展 PhpRedis,代碼還依賴(lài)于 Carbon 庫(kù),用于處理時(shí)間。代碼量很少,所以就不敲注釋了。
<?php
namespace Blog\Redis;
use \Redis;
use Carbon\Carbon;
class Ranks {
const PREFIX = 'rank:';
protected $redis = null;
public function __construct(Redis $redis) {
$this->redis = $redis;
}
public function addScores($member, $scores) {
$key = self::PREFIX . date('Ymd');
return $this->redis->zIncrBy($key, $scores, $member);
}
protected function getOneDayRankings($date, $start, $stop) {
$key = self::PREFIX . $date;
return $this->redis->zRevRange($key, $start, $stop, true);
相關(guān)文章
關(guān)于Redis?bigkeys命令會(huì)阻塞問(wèn)題的解決
這篇文章主要介紹了關(guān)于Redis?bigkeys命令會(huì)阻塞問(wèn)題的解決,今天分享一次Redis引發(fā)的線上事故,避免再次踩雷,實(shí)現(xiàn)快速入門(mén),需要的朋友可以參考下2023-03-03
Redis6 主從復(fù)制及哨兵機(jī)制的實(shí)現(xiàn)
本文主要介紹了Redis6 主從復(fù)制及哨兵機(jī)制的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
淺析PHP分布式中Redis實(shí)現(xiàn)Session的方法
這篇文章主要介紹了PHP分布式中Redis實(shí)現(xiàn)Session的方法,文中詳細(xì)介紹了兩種方法的使用方法,并給出了測(cè)試的示例代碼,有需要的朋友可以參考借鑒,下面來(lái)一起看看吧,2016-12-12
Redis實(shí)現(xiàn)會(huì)話管理和token認(rèn)證的示例代碼
會(huì)話管理和身份認(rèn)證是實(shí)現(xiàn)用戶登錄、權(quán)限管理等功能的基礎(chǔ),本文主就來(lái)介紹一下Redis實(shí)現(xiàn)會(huì)話管理和token認(rèn)證的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2025-04-04
Redis和springboot 整合redisUtil類(lèi)的示例代碼
這篇文章主要介紹了Redis和springboot 整合redisUtil類(lèi)的示例代碼,本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12

