SortedSet如何實(shí)現(xiàn)多維度排序

說明:本次實(shí)踐基于Redis版本3.2.11。

關(guān)于SortedSet

首先苛让,我們都知道Redis的SortedSet是可以根據(jù)score進(jìn)行排序的,以手機(jī)應(yīng)用商店的熱門榜單排序?yàn)槔鶕?jù)下載量倒序排列混萝,其簡(jiǎn)單用法如下:

127.0.0.1:6379> zadd TopApp 12000000 wechat
(integer) 1
127.0.0.1:6379> zadd TopApp 8000000 taobao 10000000 alipay
(integer) 2
127.0.0.1:6379> ZREVRANGE TopApp 0 -1
1) "wechat"
2) "alipay"
3) "taobao"

對(duì)SortedSet做一下簡(jiǎn)單總結(jié):

  1. 默認(rèn)升序排列,即通過命令ZRANGE實(shí)現(xiàn)萍恕;如果要按照降序排列逸嘀,需要通過命令ZREVRANGE實(shí)現(xiàn);
  2. 當(dāng)score即得分一樣時(shí)允粤,按照字典順序對(duì)member進(jìn)行排序崭倘,字典排序用的是二進(jìn)制翼岁,它比較的是字符串的字節(jié)數(shù)組,所以實(shí)際上是比較ASCII碼司光。

簡(jiǎn)單用法介紹完后琅坡,接下來給出幾種方案,介紹如何利用Redis實(shí)現(xiàn)多維度排序残家。同樣的榆俺,還是以手機(jī)應(yīng)用商店的熱門榜單排序?yàn)槔菏紫劝凑誂PP的下載量倒序排序,如果下載量一樣坞淮,則按照最后更新時(shí)間倒序排列茴晋。

方案1

介紹的第一個(gè)方案,并不需要依賴SortedSet回窘,它的實(shí)現(xiàn)非常簡(jiǎn)單诺擅,但是需要產(chǎn)品做簡(jiǎn)單的妥協(xié),即不能實(shí)時(shí)更新榜單啡直。其實(shí)現(xiàn)方案是:定時(shí)每隔1分鐘(可以由產(chǎn)品確定時(shí)間間隔)通過SQL(select * from tb_apps order by download_count desc, updated_time desc limit 300)或者其他方式計(jì)算熱門榜單掀虎,然后把TOP300用List結(jié)構(gòu)保存到緩存中。

說明:根據(jù)應(yīng)用商店的用戶行為分析付枫,真實(shí)用戶很少會(huì)預(yù)覽10頁以后的數(shù)據(jù)烹玉,即使有這種用戶,我們也可以忽略掉阐滩。所以只需要將總計(jì)10頁二打,即10x30=300個(gè)APP信息用List結(jié)構(gòu)保存即可。分頁取數(shù)據(jù)時(shí)掂榔,通過lrange命令即可輕松實(shí)現(xiàn)继效。

這種方案雖然簡(jiǎn)單,但是非常有用装获。即使不能做到實(shí)時(shí)瑞信,但是并沒有影響用戶體驗(yàn)。在項(xiàng)目初期需要快速發(fā)布穴豫,是一個(gè)比較推薦的做法凡简。

方案2

方案2就是本文重點(diǎn)介紹的利用SortedSet實(shí)現(xiàn)多維度排序。關(guān)注公眾號(hào):【阿飛的博客】精肃,更多原創(chuàng)首發(fā)秤涩!

介紹方案之前,我們?cè)倏匆幌耂ortedSet排序因子score司抱,它是一個(gè)雙精度64位的浮點(diǎn)型數(shù)字字符串筐眷。+inf和-inf都是有效值,能包括的整數(shù)范圍是-(2^53) 到 +(2^53)习柠,或者說是-9007199254740992 到 9007199254740992匀谣。

那么照棋,我們?nèi)绾螌?shí)現(xiàn)多維度排序呢?答案是構(gòu)造一個(gè)特殊的score武翎。以本文案例為例必怜,排序影響因子是下載量和更新時(shí)間,那么我們可以構(gòu)造一個(gè)這樣特殊的浮點(diǎn)類型的score:整數(shù)部分就是下載量后频,小數(shù)部分就是最后更新時(shí)間戳梳庆。

talk is cheap,show me the code卑惜。假設(shè)有5個(gè)app的下載量和最后更新時(shí)間分別如下(說明:更新時(shí)間只精確到秒):

wechat-下載量:12000000膏执,最后更新時(shí)間:1564022201;其score為:12000000.1564022201
qq-下載量:12000000露久,最后更新時(shí)間:1564022222更米;其score為:12000000.1564022222
tiktok-下載量:9808900,最后更新時(shí)間:1563552267毫痕;其score為:9808900.1563552267
taobao-下載量:11006600征峦,最后更新時(shí)間:1564345601;其score為:11006600.1564345601
alipay-下載量:11006600消请,最后更新時(shí)間:1564345600栏笆;其score為:11006600.1564345600

接下來,我們通過如下命令將這5個(gè)APP用SortedSet數(shù)據(jù)類型保存到Redis中:

zadd TopApp 12000000.1564022201 wechat 12000000.1564022222 qq 9808900.1563552267 tiktok 11006600.1564345601 taobao 11006600.1564345600 alipay

保存后臊泰,我們看一下排序結(jié)果是否符合我們的預(yù)期:

127.0.0.1:6379> zrevrange TopApp 0 -1
1) "qq"
2) "wechat"
3) "taobao"
4) "alipay"
5) "tiktok"

寫在最后

是不是很完美蛉加?

還不完美,這種討巧的方式只能實(shí)現(xiàn)二維排序缸逃。如果有三維排序针饥,四維排序呢?這里筆者提供一種實(shí)現(xiàn)參考需频,即自定義得分權(quán)重計(jì)算公式丁眼,例如:downloadCount*1000+updatedTime;昭殉,這種實(shí)現(xiàn)無論排序維度多少都搞得定苞七,需要注意的是,在具體實(shí)現(xiàn)時(shí)一定注意不要讓score溢出:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末饲化,一起剝皮案震驚了整個(gè)濱河市莽鸭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吃靠,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件足淆,死亡現(xiàn)場(chǎng)離奇詭異巢块,居然都是意外死亡礁阁,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門族奢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來姥闭,“玉大人,你說我怎么就攤上這事越走∨锲罚” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵廊敌,是天一觀的道長(zhǎng)铜跑。 經(jīng)常有香客問我,道長(zhǎng)骡澈,這世上最難降的妖魔是什么锅纺? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮肋殴,結(jié)果婚禮上囤锉,老公的妹妹穿的比我還像新娘。我一直安慰自己护锤,他們只是感情好官地,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著烙懦,像睡著了一般区丑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上修陡,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天沧侥,我揣著相機(jī)與錄音,去河邊找鬼魄鸦。 笑死宴杀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拾因。 我是一名探鬼主播旺罢,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绢记!你這毒婦竟也來了扁达?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤蠢熄,失蹤者是張志新(化名)和其女友劉穎跪解,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體签孔,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叉讥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年窘行,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片图仓。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡罐盔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出救崔,到底是詐尸還是另有隱情惶看,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布六孵,位于F島的核電站纬黎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏狸臣。R本人自食惡果不足惜莹桅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望烛亦。 院中可真熱鬧诈泼,春花似錦、人聲如沸煤禽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽檬果。三九已至瓮孙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間选脊,已是汗流浹背杭抠。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恳啥,地道東北人偏灿。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像钝的,于是被迫代替她去往敵國(guó)和親翁垂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354