比如講資料儲存在了 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,摘自
<?phpnamespace
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...