redis zset做排行榜

2022-05-17 01:39:11 字數 2668 閱讀 6257

直播運營活動中經常會有這樣的需求,根據使用者送禮情況做排名。這個排行榜具有以下特點:

使用者每次請求會返回使用者的排名

送禮金額越多粉絲排名越靠前

相同金額送禮越早越靠前

排行榜會隨著粉絲送禮變化而不斷變化

表結構

create table `user` (

`id` int(10) not null comment '編號',

`uid` varchar(32) not null comment '使用者',

`coin` int(10) not null comment '使用者送出金額',

`create_time` datetime not null comment '建立時間',

`update_time` datetime not null comment '更新時間',

primary key (`id`),

unique key `uid` (`uid`)

) engine=innodb default charset=utf8 comment='使用者表';

1. sql查詢

explain select

*from

(select

@rank := @rank + 1 as rank,

s.uid as uid,

s.coin as coin

from

`user` s,

(select @rank := 0) r

order by

coin desc,

create_time

) qwhere

q.uid = 'xiaoming';

根據 select @rank 與 user表結合起來作為一張有排名的新錶,然後再從中找出某個使用者的排名。這種方法的優點是簡單,每次使用者來請求,只要用這個sql查一下即可;缺點是這個算是比較複雜的sql,查起來太慢,每次都要全表查詢,試了幾次都要0.5s左右。用explain分析如下:

2. user中新增rank欄位

在user中新增rank欄位,寫個計畫任務每隔2分鐘全表掃瞄,然後更新rank名次字段。這個方法最殘暴,但是也是最不可取的。首先會產生延遲,因為2分鐘才更新一次名次,其次,每次都要更新全部資料,給資料庫很大的壓力,最後,計畫任務更新資料的時候,使用者送禮也在更新資料,稍微不注意就會出現髒讀的情況。

3. 用redis的zset資料結構

zset的相關api (pipelinecluster/jedis)

插入或者更新資料

long zadd(final string key, final double score, final string member)

key : 排行榜的名字

memeber : 使用者

score : 使用者的分數

獲取使用者分數

double zscore(string key, final string member)

獲取使用者的排名

long zrevrank(final string key, final string member):(score從大到小,從0開始,所以需要加1)

long zrank(final string key, final string member):(score從小到大,從0開始,所以需要加1)

獲取某個範圍內的使用者排名

setzrevrangewithscoresbytes(string key, final long start, final long end) (從大到小)

setzrangewithscoresbytes(string key, final long start, final long end) (從小到大)

start : 開始排名

end : 結束排名

tuple :

public class tuple implements comparable 

比如我們想查1-10的排名,我們可以zrevrangewithscoresbytes(key, 0, 9)排行榜的實現

簡單簡單的排行榜就是每次使用者資訊更新後,把使用者uid和使用者coin都更新到zset中,這個的好處是比較簡單,有一點不好的就是他不能實現先到先得,即先相同金額送禮越早越靠前。

較複雜(可實現先到先得)

/**

* 將coin加密成可以存在zset的值,實際上就是 coin * 10000000 + now % 10000000

* @param coin

* @return

*/public static double encrypt(long coin)

/*** 將zset的值轉成long型的coin

* @param value

* @return

*/public static long decrypt(double value)

Redis Zset實現排行榜功能

使用redis 的zset資料結構 首先搞清楚zset 新增儲存的命令 對理解和設計排行榜起到至關重要的作用 zadd key value1 member1 value2 member2.key string型別 value 數值型別 member string型別 zset底層根據value自動進...

redis set輕鬆做排行榜應用

author pako email zealzpc gmail.com 最近專案有很多功能要做類似排行榜的功能,當然其實用python來做不難,不過因為排行榜的資料是要做持久化存在資料庫裡的,如果每次用sql 去查詢在做排序 當資料量多起來後會效能很差,而且畢竟還要自己去寫相應的操作特別是要查詢乙個...

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 ...