您好,登錄后才能下訂單哦!
今天小編就為大家帶來一篇有關Redis制作排行榜系統的文章。小編覺得挺實用的,為此分享給大家做個參考。一起跟隨小編過來看看吧。
redis里有一種很特殊的數據類型——有序集合。之前我們學過的集合的概念是,集合里所有元素都是唯一的、無序的。但這里怎么出現了有序集合,他是怎么來實現有序的呢?
有序集合里元素還是唯一的,但會給每個元素設置一個socre(分值),通過這個分值來實現有序的。如下圖所示:
有序集合API
下面介紹幾個有序集合的API,實現排行榜功能需要知道這些API的用法。
zAdd
我們想設置一個球員2k能力值的有序列表,使用球員名為元素,能力值為scores。
庫里的投射能力為100,詹姆斯為92,哈登為96,保羅為97
sadd一次可以添加1個或多個元素
127.0.0.1:6379[1]> zadd 2kplayer:shoot 100 curry (integer) 1 127.0.0.1:6379[1]> zadd 2kplayer:shoot 92 james 96 harden 97 paul (integer) 3
zIncrBy
這一個月來,哈登連續爆種,瘋狂連續砍高分,那么,2k決定將他的投射能力值提高2點
127.0.0.1:6379[1]> zincrby 2kplayer:shoot 2 harden "98"
zRange、zRevRange
現在我們想知道能力值前3名的球員是哪3個。
127.0.0.1:6379[1]> zrange 2kplayer:shoot 0 2 withscores 1) "james" 2) "92" 3) "paul" 4) "97" 5) "harden" 6) "98"
redis默認采用正序,分值從小到大排序。所以我們需要使用zRevRange
127.0.0.1:6379[1]> zrevrange 2kplayer:shoot 0 2 withscores 1) "curry" 2) "100" 3) "harden" 4) "98" 5) "paul" 6) "97"
zUnionStore
2k能力值是有多方面的,投射只是其中一項,速度、上籃等都是能力值的一部分。
127.0.0.1:6379[1]> zadd 2kplayer:speed 99 james 90 paul 90 curry 93 harden (integer) 4
這時候,想知道球員綜合能力值的話,就需要將每一項的得分都加起來
127.0.0.1:6379[1]> zunionstore 2kplayer 2 2kplayer:shoot 2kplayer:speed (integer) 4 127.0.0.1:6379[1]> zrange 2kplayer 0 -1 withscores 1) "paul" 2) "187" 3) "curry" 4) "190" 5) "harden" 6) "191" 7) "james" 8) "191"
實現排行榜系統
場景如下:一個視頻點播系統,每天觀看的人很多。該系統有個榜單功能,展示觀看量最多的視頻。分為今日榜單、三日榜單、一周排行、月榜單。
思路:首先是按天統計視頻觀看次數,然后再統計出今日榜單、三日榜單等。
統計視頻觀看次數的偽代碼如下:
// 觀看視頻 function view ($videoId) { $key = 'video:view:'.date('Y-m-d'); if (!$redis->exists($key)) { $redis->zIncrBy($key, 1, $videoId); $redis->expire($key, 86400 * 30); } $redis->zIncrBy($key, 1, $videoId); }
今日最熱
今日最熱有一個注意點,當新的一天剛開始時,數據可能為空或很少。所以,我們可以將今日和昨日的數據合并起來,但將今日的數據權重設高些。
今日最熱功能實現偽代碼如下:
function todayHot () { $tokeyKey = 'video:view:'.date('Y_m_d'); $yesKey = 'video:view:'. date('Y_m_d', time() - 86400); $keyUnion = "view:rank:today"; $redis->zUnionStore($keyUnion, [$tokeyKey, $yesKey], [10, 1]); // 取前100名 return $redis->zRevRange($keyUnion, 0, 99); }
三日榜單
function threeHot () { $keyUnion = 'view:rank:three'; $unionKeys = []; for ($i=0; $i < 3; $i++) { $unionKeys[] = 'video:view:'.date('Y_m_d', time() - 86400 *$i); } $redis->zUnionStore($keyUnion, $unionKeys); return $redis->zRevRange($keyUnion, 0, 99, true); }
周榜單、月榜單等和三日榜單的思路完成一樣,所以就不貼出代碼了。
關于Redis制作排行榜系統就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果喜歡這篇文章,不如把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。