欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

手把手教你使用redis實(shí)現(xiàn)排行榜功能

 更新時(shí)間:2023年04月14日 10:58:53   作者:Java是最nb的語(yǔ)言  
使用Redis中有序集合的特性來(lái)實(shí)現(xiàn)排行榜是又好又快的選擇,一般排行榜都是有實(shí)效性的,比如“用戶積分榜”,下面這篇文章主要給大家介紹了關(guān)于使用redis實(shí)現(xiàn)排行榜功能的相關(guān)資料,需要的朋友可以參考下

一、需求背景

最近項(xiàng)目需要做排行榜功能,實(shí)現(xiàn)員工邀請(qǐng)用戶注冊(cè)排行榜,要求是實(shí)時(shí)更新,查詢要快。員工所屬支行、二級(jí)行、省行,界面要根據(jù)條件顯示排名數(shù)據(jù)。效果如下圖所示:

原型圖展示比較隨意,用excel隨便寫了一下,湊合著看。

二、實(shí)現(xiàn)思路  

1、利用數(shù)據(jù)庫(kù)

建一張統(tǒng)計(jì)表,字段包括:邀請(qǐng)人、邀請(qǐng)人所屬支行、邀請(qǐng)人所屬二級(jí)行、被邀請(qǐng)人、注冊(cè)時(shí)間等關(guān)鍵信息,用于sql統(tǒng)計(jì)排名,根據(jù)條件使用group by相關(guān)字段,比較簡(jiǎn)單,這個(gè)大家應(yīng)該清楚。

數(shù)據(jù)量小,統(tǒng)計(jì)效率還可以。但是支行下有十幾萬(wàn)員工,一個(gè)員工邀請(qǐng)10個(gè)就百萬(wàn)數(shù)據(jù),如果更多,數(shù)據(jù)就更大了,統(tǒng)計(jì)效率不高。下面重點(diǎn)討論用第二種方式實(shí)現(xiàn)。

2、利用redis

我們都知道redis基于內(nèi)存實(shí)現(xiàn)的,查詢效率極高,且支持多種數(shù)據(jù)類型,其中zset是本次實(shí)現(xiàn)功能的關(guān)鍵。

  • ZSet也是String類型元素的集合,且不允許重復(fù)的成員;
  • 不同的是每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè)double類型的分?jǐn)?shù),剛好也是我們需要的邀請(qǐng)用戶數(shù);
  • 通過(guò)分?jǐn)?shù)來(lái)為集合中的成員進(jìn)行排序。ZSet的成員是唯一的,但分?jǐn)?shù)(score)卻可以重復(fù);

基于上面的特性,滿足我們本次的需求。好了,說(shuō)了一大堆廢話,下面將進(jìn)入正題。

首先,捋一下查詢條件,根據(jù)前面的效果圖,可以看出有以下幾種情況:

  1. 二級(jí)行的全部排名以及日周月榜排名
  2. 支行在省行的全部排名以及日周月榜排名
  3. 支行在二級(jí)行的全部排名以及日周月榜排名
  4. 員工在省行的全部排名以及日周月榜排名
  5. 員工在二級(jí)行的全部排名以及日周月榜排名
  6. 員工在支行的全部排名以及日周月榜排名

基于redis的Zset函數(shù)incrementScore,我們很快就能發(fā)現(xiàn),其實(shí)實(shí)現(xiàn)各個(gè)排名,只要把key規(guī)定好即可,例如:

  • 員工在省行的全部排名key,可以設(shè)置為 rank:employee:省行
  • 員工在省行的日排行榜key,可以設(shè)置為 rank:emploee:省行:當(dāng)天日期

下面我們來(lái)實(shí)現(xiàn)其中的上面的兩個(gè)排行:

String key = "rank:employee:廣東省";
redisTemplate.opsForZSet().incrementScore(key, "張三", 10);
redisTemplate.opsForZSet().incrementScore(key, "李四", 8);
redisTemplate.opsForZSet().incrementScore(key, "王五", 5);

執(zhí)行完后,redis會(huì)保存為如下數(shù)據(jù):

 這樣的話,有了上面的數(shù)據(jù),可以用redis的提供的函數(shù)把排行榜查出來(lái),代碼如下:

String key = "rank:employee:廣東省";
Set<ZSetOperations.TypedTuple<String>> set = redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, -1);
JSONArray jsonArray = JSONObject.parseArray(JSONObject.toJSONString(set));
for(int i = 0, size = jsonArray.size(); i < size; i++) {
    JSONObject o = JSONObject.parseObject(jsonArray.get(i).toString());
    System.out.println("員工:" + o.getString("value") + ", 邀請(qǐng)人數(shù):" + o.getLongValue("score"));
}

reverseRangeWithScores方法接收三個(gè)參數(shù),第一個(gè)是key,后面兩個(gè)是分頁(yè)查詢,起始是從0開(kāi)始,-1表示全部,如果設(shè)置為0,4,那么就是查詢前5條記錄,查出結(jié)果如下:

以上就實(shí)現(xiàn)了員工在省行的排名。類似的,員工要實(shí)現(xiàn)在省行的日榜,代碼如下:

String key = "rank:employee:廣東省:2022-09-01";
redisTemplate.opsForZSet().incrementScore(key, "張三", 10);
redisTemplate.opsForZSet().incrementScore(key, "李四", 8);
redisTemplate.opsForZSet().incrementScore(key, "王五", 5);

 執(zhí)行完后,redis會(huì)保存為如下數(shù)據(jù)(這里我多設(shè)置了前一天的數(shù)據(jù)):

一樣的,用 reverseRangeWithScores方法可以把上面的結(jié)果查出來(lái)。

至于周榜、月榜,可以把每一天的數(shù)據(jù)累加起來(lái),再做個(gè)排名,redis已經(jīng)幫我們實(shí)現(xiàn)了這個(gè)功能,代碼如下:

Date date = DateUtil.date();
//獲取本周的第一天
DateTime beginOfWeek = DateUtil.beginOfWeek(date);
//到今天一共有幾天
long diffDay = DateUtil.between(date, beginOfWeek, DateUnit.DAY) + 1;
 
List<String> keys = new ArrayList<>();
for(int i = 0; i < diffDay; i++) {
    //把需要查詢的天數(shù)放一起
    keys.add("rank:employee:廣東省:" + DateUtil.formatDate(DateUtil.offsetDay(beginOfWeek, i)));
}
 
//redis使用unionAndStore做合并,將結(jié)果集放在另一個(gè)的key,也就是第三個(gè)參數(shù)
redisTemplate.opsForZSet().unionAndStore("weekRank", keys, "employeeRankWeek");
 
//查詢結(jié)果集用employeeRankWeek這個(gè)key
Set<ZSetOperations.TypedTuple<String>> set = redisTemplate.opsForZSet().reverseRangeWithScores("employeeRankWeek", 0, -1);
JSONArray jsonArray = JSONObject.parseArray(JSONObject.toJSONString(set));
for(int i = 0, size = jsonArray.size(); i < size; i++) {
    JSONObject o = JSONObject.parseObject(jsonArray.get(i).toString());
    System.out.println("員工:" + o.getString("value") + ", 本周邀請(qǐng)人數(shù):" + o.getLongValue("score"));
}

注意代碼里面說(shuō)的,redis會(huì)把結(jié)果合并到另一個(gè)key,在redis上也可以看到,如下圖:

查出來(lái)的結(jié)果如下圖:

其實(shí)我們會(huì)發(fā)現(xiàn),本周榜、本月榜無(wú)需保存每一天的數(shù)據(jù),只要把key設(shè)置為本周或本月的第一天就可以,因?yàn)樘砑訑?shù)據(jù)的那一刻就知道是哪一周或哪月了。

例如:key = rank:employee:廣東省:2022-08-29,8月29日是本周的第一天,無(wú)論你在接下來(lái)一周內(nèi)邀請(qǐng)多少人,都是在本周內(nèi)完成的,在這個(gè)基礎(chǔ)上累加邀請(qǐng)數(shù)量即可。本月榜的邏輯也是一樣。

查詢的時(shí)候,獲取當(dāng)前時(shí)間本周或本月的第一天,就可以實(shí)現(xiàn)本周、本月排行了。

String key = "rank:employee:廣東省";
Date date = DateUtil.date();
 
String week = DateUtil.formatDate(DateUtil.beginOfWeek(date));
String month = DateUtil.formatDate(DateUtil.beginOfMonth(date));
 
//周榜
redisTemplate.opsForZSet().incrementScore(key+":week:"+week, "張三", 17);
//月榜
redisTemplate.opsForZSet().incrementScore(key+":month:"+month, "張三", 17);

當(dāng)然了,如果要查詢歷史的排行,這種設(shè)計(jì)就滿足不了了,還是要保存每天的數(shù)據(jù)才行。

總結(jié)

到此這篇關(guān)于使用redis實(shí)現(xiàn)排行榜功能的文章就介紹到這了,更多相關(guān)redis實(shí)現(xiàn)排行榜功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis實(shí)現(xiàn)限流器的三種方法(小結(jié))

    Redis實(shí)現(xiàn)限流器的三種方法(小結(jié))

    本文主要介紹了Redis實(shí)現(xiàn)限流器的三種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Redis生成分布式系統(tǒng)全局唯一ID的實(shí)現(xiàn)

    Redis生成分布式系統(tǒng)全局唯一ID的實(shí)現(xiàn)

    在互聯(lián)網(wǎng)系統(tǒng)中,并發(fā)越大的系統(tǒng),數(shù)據(jù)就越大,數(shù)據(jù)越大就越需要分布式,本文主要介紹了Redis生成分布式系統(tǒng)全局唯一ID的實(shí)現(xiàn),感興趣的可以了解一下
    2021-10-10
  • Redis讀寫分離搭建的完整步驟

    Redis讀寫分離搭建的完整步驟

    為滿足讀多寫少的業(yè)務(wù)場(chǎng)景.最大化節(jié)約用戶成本.云數(shù)據(jù)庫(kù)Redis版推出了讀寫分離規(guī)格,為用戶提供透明、高可用、高性能、高靈活的讀寫分離服務(wù),這篇文章主要給大家介紹了關(guān)于Redis讀寫分離搭建的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • Redis全文搜索教程之創(chuàng)建索引并關(guān)聯(lián)源數(shù)據(jù)的教程

    Redis全文搜索教程之創(chuàng)建索引并關(guān)聯(lián)源數(shù)據(jù)的教程

    RediSearch提供了一種簡(jiǎn)單快速的方法對(duì) hash 或者 json 類型數(shù)據(jù)的任何字段建立二級(jí)索引,然后就可以對(duì)被索引的 hash 或者 json 類型數(shù)據(jù)字段進(jìn)行搜索和聚合操作,這篇文章主要介紹了Redis全文搜索教程之創(chuàng)建索引并關(guān)聯(lián)源數(shù)據(jù),需要的朋友可以參考下
    2023-12-12
  • Redis中一些最常見(jiàn)的面試問(wèn)題總結(jié)

    Redis中一些最常見(jiàn)的面試問(wèn)題總結(jié)

    Redis在互聯(lián)網(wǎng)技術(shù)存儲(chǔ)方面使用如此廣泛,幾乎所有的后端技術(shù)面試官都要在Redis的使用和原理方面對(duì)小伙伴們進(jìn)行各種刁難。下面這篇文章主要給大家總結(jié)介紹了關(guān)于Redis中一些最常見(jiàn)的面試問(wèn)題,需要的朋友可以參考下
    2018-09-09
  • Redis RDB技術(shù)底層原理詳解

    Redis RDB技術(shù)底層原理詳解

    為了使Redis在重啟之后仍能保證數(shù)據(jù)不丟失,需要將數(shù)據(jù)從內(nèi)存中以某種形式同步到硬盤中,這一過(guò)程就是持久化,本文重點(diǎn)給大家介紹Redis RDB技術(shù)底層原理實(shí)現(xiàn)方法,一起看看吧
    2021-09-09
  • 詳解redis desktop manager安裝及連接方式

    詳解redis desktop manager安裝及連接方式

    這篇文章主要介紹了redis desktop manager安裝及連接方式,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • redis不能訪問(wèn)本機(jī)真實(shí)ip地址的解決方案

    redis不能訪問(wèn)本機(jī)真實(shí)ip地址的解決方案

    這篇文章主要介紹了redis不能訪問(wèn)本機(jī)真實(shí)ip地址的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 如何使用Redis實(shí)現(xiàn)電商系統(tǒng)的庫(kù)存扣減

    如何使用Redis實(shí)現(xiàn)電商系統(tǒng)的庫(kù)存扣減

    在日常開(kāi)發(fā)中有很多地方都有類似扣減庫(kù)存的操作,本文主要介紹了如何使用Redis實(shí)現(xiàn)電商系統(tǒng)的庫(kù)存扣減,具有一定的參考價(jià)值,感興趣的可以了解一下
    2022-01-01
  • Redis如何一鍵部署腳本

    Redis如何一鍵部署腳本

    這篇文章主要介紹了Redis如何一鍵部署腳本,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04

最新評(píng)論