原文連結:https://www.cnblogs.com/chenzhuantou/p/11321848.html
1、前言
實作一個排版榜,我們通常想到的就是mysql的order by 簡單粗暴就撸出來了。但是這樣真的優雅嗎?
資料庫是系統的瓶頸,這是衆所周知的。如果給你一張百萬的表,讓你排序做排行榜,花費的時間是十分可怕的。
不如緩存吧,order by的時候強制使用索引。但是這樣真的優雅嗎?

我們分析一下排行榜,一個使用者一個排名,意味着要去重,這時我們會想到Java的一種資料結構Set。不過Set又是無序的。有沒有一種結構是可以保住元素唯一以及有序的呢。
幸運的是,還真的有。Redis的ZSet的就是這樣的一種資料結構。Zset裡面的元素是唯一的,有序的,按分數從小到大排序。作為一名優秀的crud程式員,我們從這幾個方方面入手了解zset結構。
2.1、ZADD 增加與修改
其時間複雜度為 O(M*log(N)), N 是有序集的基數, M 為成功添加的新成員的數量。如果key不存在就插入,存在就更新。
使用如下:
說明:
page_rankde 是key,10是分數,google.com是value。
2.2、ZRANK 查詢
時間複雜度: O(log(N))
使用如下:
說明:
salary的key,tom是value,隻要輸入特定的key與value就能查詢到對應的排名。
del 删除
直接使用redis的del指令
回到排行榜的實作,要利用zset結構來實作的話,重要的是如何設計分數。分析一下排行榜單的設計。如果排行榜的設計按一個次元比如金币數量,那隻需把其數量取反作為分數score即可。取反是因為zset預設從小到大排序。
實作如下:
如果排行榜的設計按兩個次元比如金币數量和用時。由于score是一個可以double類型的參數,設計的時候可以把用時作為小數,用一天的總毫秒數減去花費毫秒數作為小數部分,然後當做字元串拼接起來,然後取反作為score。
實作如下:
代碼實作
需要全部源碼的請加我微信:xttblog,備注:“排行榜源碼”,免費發你!