成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

使用 Redis 實現(xiàn)排行榜功能

MoAir / 2304人閱讀

摘要:排行榜功能是一個很普遍的需求。使用中有序集合的特性來實現(xiàn)排行榜是又好又快的選擇。一般排行榜都是有實效性的,比如用戶積分榜。比如昨日積分榜利用并集實現(xiàn)多天的積分總和,實現(xiàn)上周積分榜這樣就將天的積分記錄合并到有序集合中了。

排行榜功能是一個很普遍的需求。使用 Redis 中有序集合的特性來實現(xiàn)排行榜是又好又快的選擇。

一般排行榜都是有實效性的,比如“用戶積分榜”。如果沒有實效性一直按照總榜來排,可能榜首總是幾個老用戶,對于新用戶來說,那真是太令人沮喪了。

首先,來個“今日積分榜”吧,排序規(guī)則是今日用戶新增積分從多到少。

那么用戶增加積分時,都操作一下記錄當(dāng)天積分增加的有序集合。
假設(shè)今天是 2015 年 04 月 01 日,UID 為 1 的用戶因為某個操作,增加了 5 個積分。
Redis 命令如下:

bashZINCRBY rank:20150401 5 1

假設(shè)還有其他幾個用戶也增加了積分:

bashZINCRBY rank:20150401 1 2
ZINCRBY rank:20150401 10 3

看看現(xiàn)在有序集合 rank:20150401 中的數(shù)據(jù)(withscores 參數(shù)可以附帶獲取元素的 score):

bashZRANGE rank:20150401 0 -1 withscores
bash1) "2"
2) "1"
3) "1"
4) "5"
5) "3"
6) "10"

按照分?jǐn)?shù)從高到低,獲取 top10:

bashZREVRANGE rank:20150401 0 9 withscores
bash1) "3"
2) "10"
3) "1"
4) "5"
5) "2"
6) "1"

因為只有三個元素,所以就查詢出了這些數(shù)據(jù)。

如果每天記錄當(dāng)天的積分排行榜,那么其他花樣百出的榜單也就簡單了。
比如“昨日積分榜”:

bashZREVRANGE rank:20150331 0 9 withscores

利用并集實現(xiàn)多天的積分總和,實現(xiàn)“上周積分榜”:

bashZUNIONSTORE rank:last_week 7 rank:20150323 rank:20150324 rank:20150325 rank:20150326 rank:20150327 rank:20150328 rank:20150329 WEIGHTS 1 1 1 1 1 1 1

這樣就將 7 天的積分記錄合并到有序集合 rank:last_week 中了。權(quán)重因子 WEIGHTS 如果不給,默認(rèn)就是 1。為了不隱藏細(xì)節(jié),特意寫出。
那么查詢上周積分榜 Top10 的信息就是:

bashZREVRANGE rank:last_week  0 9 withscores

“月度榜”、“季度榜”、“年度榜”等等就以此類推。

下面給出一個 PHP 版的簡單實現(xiàn)。使用 Redis 依賴于 PHP 擴(kuò)展 PhpRedis,代碼還依賴于 Carbon 庫,用于處理時間。代碼量很少,所以就不敲注釋了。

phpredis = $redis;
    }


    public function addScores($member, $scores) {
        $key = self::PREFIX . date("Ymd");
        return $this->redis->zIncrBy($key, $scores, $member);
    }


    protected function getOneDayRankings($date, $start, $stop) {
        $key = self::PREFIX . $date;
        return $this->redis->zRevRange($key, $start, $stop, true);
    }


    protected function getMultiDaysRankings($dates, $outKey, $start, $stop) {
        $keys = array_map(function($date) {
            return self::PREFIX . $date;
        }, $dates);

        $weights = array_fill(0, count($keys), 1);
        $this->redis->zUnion($outKey, $keys, $weights);
        return $this->redis->zRevRange($outKey, $start, $stop, true);
    }


    public function getYesterdayTop10() {
        $date = Carbon::now()->subDays(1)->format("Ymd");
        return $this->getOneDayRankings($date, 0, 9);
    }


    public static function getCurrentMonthDates() {
        $dt = Carbon::now();
        $days = $dt->daysInMonth;

        $dates = array();
        for ($day = 1; $day <= $days; $day++) {
            $dt->day = $day;
            $dates[] = $dt->format("Ymd");
        }
        return $dates;
    }


    public function getCurrentMonthTop10() {
        $dates = self::getCurrentMonthDates();
        return $this->getMultiDaysRankings($dates, "rank:current_month", 0, 9);
    }

}

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/30218.html

相關(guān)文章

  • Redis 的 8 大應(yīng)用場景!

    摘要:之前講過的介紹,及使用帶來的優(yōu)勢,這章整理了一下的應(yīng)用場景,也是非常重要的,學(xué)不學(xué)得好,能正常落地是關(guān)鍵。下面一一來分析下的應(yīng)用場景都有哪些。提供的有序集合數(shù)據(jù)類構(gòu)能實現(xiàn)各種復(fù)雜的排行榜應(yīng)用。 之前講過Redis的介紹,及使用Redis帶來的優(yōu)勢,這章整理了一下Redis的應(yīng)用場景,也是非常重要的,學(xué)不學(xué)得好,能正常落地是關(guān)鍵。 下面一一來分析下Redis的應(yīng)用場景都有哪些。 1、緩存...

    CastlePeaK 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<