php redis實現排行榜(demo)

2022-03-22 23:48:29 字數 3832 閱讀 999

比如講資料儲存在了 redis 的有序集合 user_score 中,使用 redis 來統計玩家排行榜的資料。

首先我們需要思考的是,乙個典型的遊戲排行榜都包括哪些功能呢?

統計全部玩家的排行榜

按名次查詢排名前 n 名的玩家

查詢某個玩家的分數

查詢某個玩家的排名

對玩家的分數和排名進行更新

查詢指定玩家前後 m 名的玩家

增加或移除某個玩家,並對排名進行更新

在 redis 中實現上面的功能非常簡單,只需要使用 redis 我們提供的方法即可,針對上面的排行榜功能需求,我們分別來看下 redis 是如何實現的。

統計全部玩家的排行榜

在 redis 裡,統計全部玩家的排行榜的命令格式為 zrevrange 排行榜名稱 起始位置 結束為止 [withscores] 。

我們使用這行命令即可:

zrevrange user_score 0 -1 withscores
我們對玩家排行榜 user_score 進行統計,其中 -1 代表的是全部的玩家資料, withscores 代表的是輸出排名的同時也輸出分數。

按名次查詢排名前 n 名的玩家

同樣我們可以使用 zrevrange 完成前 n 名玩家的排名,比如我們想要統計前 10 名玩家,可以使用: zrevrange user_score 0 9 。

查詢某個玩家的分數

命令格式為 zscore 排行榜名稱 玩家標識 。

時間複雜度為 o(1) 。

如果我們想要查詢玩家 10001 的分數可以使用: zscore user_score 10001 。

查詢某個玩家的排名

命令格式為 zrevrank 排行榜名稱 玩家標識 。

時間複雜度為 o(log(n)) 。

如果我們想要查詢玩家 10001 的排名可以使用: zrevrank user_score 10001 。

對玩家的分數進行更新,同時排名進行更新

如果我們想要對玩家的分數進行增減,命令格式為 zincrby 排行榜名稱 分數變化 玩家標識 。

時間複雜度為 o(log(n)) 。

比如我們想對玩家 10001 的分數減 1,可以使用: zincrby user_score -1 10001 。

然後我們再來檢視下玩家 10001 的排名,使用:zrevrank user_score 10001

你能看到排名由 17153 降到了 18036 名。

比如我們想要查詢玩家 10001 前後 5 名玩家都是誰,當前已知玩家 10001 的排名是 18036,那麼可以使用:zrevrange user_score 18031 18041

這樣就可以得到玩家 10001 前後 5 名玩家的資訊。

增加或刪除某個玩家,並對排名進行更新

如果我們想要刪除某個玩家,命令格式為zrem 排行榜名稱 玩家標識

時間複雜度為o(log(n))

比如我們想要刪除玩家 10001,可以使用:zrem user_score 10001

這樣我們再來查詢下排名在 18031 到 18041 的玩家是誰,使用:zrevrange user_score 18031 18041

你能看到玩家 10001 的資訊被刪除,同時後面的玩家排名都向前移了一位。

如果我們想要增加某個玩家的資料,命令格式為zadd 排行榜名稱 分數 玩家標識

時間複雜度為o(log(n))

這裡,我們把玩家 10001 的資訊再增加回來,使用:zadd user_score 93.1504697596 10001

然後我們再來看下排名在 18031 到 18041 的玩家是誰,使用:zrevrange user_score 18031 18041

你能看到插入了玩家 10001 的資料之後,排名又回來了。

下面封裝的乙個demo,摘自

<?php 

namespace

leaderboard;/**

* 使用rediszset的的商品排行榜

* @author yiwang

* */

class

redisleaderboard

else

if($leaderboard)

else}}

/*** 獲取當前的排行榜的key名

* @return string

*/public

function getleaderboard()

/*** 將對應的值填入到排行榜中

* @param $node 對應的需要填入的值(比如商品的id)

* @param number $count 對應的分數,預設值為1

* @return long 1 if the element is added. 0 otherwise.

*/public function addleaderboard($node, $count = 1

)

/*** 給出對應的排行榜

* @param int $number 需要給出排行榜數目

* @param bool $asc 排序順序 true為按照高分為第0

* @param bool $withscores 是否需要分數

* @param callback $callback 用於處理排行榜的**函式

* @return 對應排行榜

*/public function getleadboard($number, $asc = true, $withscores = false,$callback = null

) else

if($callback)

else

}/**

* 獲取給定節點的排名

* @param string $node 對應的節點的key名

* @param string $asc 是否按照分數大小正序排名, true的情況下分數越大,排名越高

* @return 節點排名,根據$asc排序,true的話,第一高分為0,false的話第一低分為0

*/public function getnoderank($node, $asc = true

)

else}}

mysql製作排行榜 mysql實現排行榜

博主新人一枚,大家可以提出自己的寶貴意見。下來我們進入正題。大家首先要了解介面的場景,再就是排行榜的規則,我們這裡說的中國式排行榜。排行榜總結了一下分為3種 中國式排行 非中國式排行1 非中國式排行2 1 1 1 2 2 2 2 2 3 3 4 4 3 5 5 4 5 6 5 7 7 select ...

redis實現排行榜

排行榜功能是乙個很普遍的需求。設想在乙個遊戲中,有上百萬的玩家資料,如果現在需要你根據玩家的經驗值整理乙個前20名的排行榜,你會怎麼做呢?你不可能 order by limit 去實現 select from game socre order by score desc limit 0,20 使用 ...

Redis 實現排行榜

不再介紹資料庫做實時排行榜的弊端,直接介紹redis的有序集合的強大作用。有序集合的資料和集合一樣,不能重複,但每個元素又可以關聯乙個分數,這個分數可以重複。需要注意的是,redis版本和命令變化較大,注意執行環境。執行環境 redis 庫版本 3.3.11 redis版本 3.2.1 生成資料 i...