最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

一、需求背景

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

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

二、實現(xiàn)思路  

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

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

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

2、利用redis

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

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

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

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

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

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

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

下面我們來實現(xiàn)其中的上面的兩個排行:

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

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

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

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") + ", 邀請人數(shù):" + o.getLongValue("score"));
}

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

以上就實現(xiàn)了員工在省行的排名。類似的,員工要實現(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會保存為如下數(shù)據(jù)(這里我多設(shè)置了前一天的數(shù)據(jù)):

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

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

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é)果集放在另一個的key,也就是第三個參數(shù)
redisTemplate.opsForZSet().unionAndStore("weekRank", keys, "employeeRankWeek");
 
//查詢結(jié)果集用employeeRankWeek這個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") + ", 本周邀請人數(shù):" + o.getLongValue("score"));
}

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

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

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

例如:key = rank:employee:廣東省:2022-08-29,8月29日是本周的第一天,無論你在接下來一周內(nèi)邀請多少人,都是在本周內(nèi)完成的,在這個基礎(chǔ)上累加邀請數(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);

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

總結(jié)

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

相關(guān)文章

  • Redis?Lua腳本實現(xiàn)ip限流示例

    Redis?Lua腳本實現(xiàn)ip限流示例

    這篇文章主要介紹了Redis?Lua腳本實現(xiàn)ip限流示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • 詳解Redis如何保證接口的冪等性

    詳解Redis如何保證接口的冪等性

    如何防止接口中同樣的數(shù)據(jù)提交,以及如何保證消息不被重復消費,這些都是shigen在學習的過程中遇到的問題,今天,趁著在學習redis的間隙,我寫了一篇文章進行簡單的實現(xiàn),需要的朋友可以參考下
    2023-11-11
  • Redis中l(wèi)ua腳本實現(xiàn)及其應用場景

    Redis中l(wèi)ua腳本實現(xiàn)及其應用場景

    本文主要介紹了Redis中l(wèi)ua腳本實現(xiàn)及其應用場景,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • Redis?的內(nèi)存淘汰策略和過期刪除策略的區(qū)別

    Redis?的內(nèi)存淘汰策略和過期刪除策略的區(qū)別

    這篇文章主要介紹了Redis?的內(nèi)存淘汰策略和過期刪除策略的區(qū)別,Redis?是可以對?key?設(shè)置過期時間的,因此需要有相應的機制將已過期的鍵值對刪除,而做這個工作的就是過期鍵值刪除策略
    2022-07-07
  • 詳解Redis實現(xiàn)分布式鎖的原理

    詳解Redis實現(xiàn)分布式鎖的原理

    分布式鎖,即分布式系統(tǒng)中的鎖,在單體應用中我們通過鎖解決的是控制共享資源訪問的問題,而分布式鎖,就是解決了分布式系統(tǒng)中控制共享資源訪問的問題,本文講給大家詳細介紹一下Redis實現(xiàn)分布式鎖的原理,需要的朋友可以參考下
    2023-09-09
  • Linux系統(tǒng)下安裝Redis數(shù)據(jù)庫過程

    Linux系統(tǒng)下安裝Redis數(shù)據(jù)庫過程

    大家好,本篇文章主要講的是Linux系統(tǒng)下安裝Redis數(shù)據(jù)庫過程,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Redis集群節(jié)點通信過程/原理流程分析

    Redis集群節(jié)點通信過程/原理流程分析

    這篇文章主要介紹了Redis集群節(jié)點通信過程/原理,詳細介紹了Cluster(集群)的節(jié)點通信的流程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • 詳解Redis中的簡單動態(tài)字符串和C字符串的區(qū)別

    詳解Redis中的簡單動態(tài)字符串和C字符串的區(qū)別

    簡單動態(tài)字符串(SDS)和?C?字符串在實現(xiàn)和特性上存在一些區(qū)別,這些區(qū)別使得?SDS?更適合作為?Redis?中字符串對象的內(nèi)部表示,本文給大家介紹一下Redis中的簡單動態(tài)字符串和C字符串的區(qū)別,需要的朋友可以參考下
    2023-12-12
  • Redis實現(xiàn)布隆過濾器的方法及原理

    Redis實現(xiàn)布隆過濾器的方法及原理

    布隆過濾器優(yōu)點是空間效率和查詢時間都比一般的算法要好的多,缺點是有一定的誤識別率和刪除困難。本文將介紹布隆過濾器的原理以及Redis如何實現(xiàn)布隆過濾器,感興趣的朋友跟隨小編一起看看吧
    2019-12-12
  • Redis實現(xiàn)短信登錄的企業(yè)實戰(zhàn)

    Redis實現(xiàn)短信登錄的企業(yè)實戰(zhàn)

    本文主要介紹了Redis實現(xiàn)短信登錄的企業(yè)實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07

最新評論

盐亭县| 木兰县| 桑植县| 蒲江县| 普宁市| 孟津县| 高尔夫| 九龙坡区| 太仓市| 察哈| 凤庆县| 西林县| 探索| 奉化市| 祥云县| 萝北县| 汤阴县| 惠东县| 光泽县| 大邑县| 山阳县| 灵武市| 宁海县| 晋中市| 会宁县| 日土县| 铜梁县| 海宁市| 长寿区| 运城市| 平度市| 石楼县| 龙川县| 探索| 冕宁县| 行唐县| 常德市| 临汾市| 秭归县| 融水| 巴东县|