亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

手把手教你使用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)字段,比較簡單,這個大家應(yīng)該清楚。

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

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

首先,捋一下查詢條件,根據(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實現(xiàn)限流器的三種方法(小結(jié))

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

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

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

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

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

    為滿足讀多寫少的業(yè)務(wù)場景.最大化節(jié)約用戶成本.云數(shù)據(jù)庫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提供了一種簡單快速的方法對 hash 或者 json 類型數(shù)據(jù)的任何字段建立二級索引,然后就可以對被索引的 hash 或者 json 類型數(shù)據(jù)字段進行搜索和聚合操作,這篇文章主要介紹了Redis全文搜索教程之創(chuàng)建索引并關(guān)聯(lián)源數(shù)據(jù),需要的朋友可以參考下
    2023-12-12
  • Redis中一些最常見的面試問題總結(jié)

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

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

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

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

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

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

    redis不能訪問本機真實ip地址的解決方案

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

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

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

    Redis如何一鍵部署腳本

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

最新評論