Redis を使用してランキング システムを完成させる

齐天大圣
リリース: 2020-05-14 09:45:25
オリジナル
2026 人が閲覧しました

redis には非常に特殊なデータ型 (順序セット) があります。以前に学んだセットの概念は、セット内のすべての要素が一意であり、順序付けされていないということです。しかし、なぜここで順序集合が登場するのでしょうか、そしてどのようにして順序を達成するのでしょうか?

順序付きセット内の要素は依然として一意ですが、要素ごとにスコア (スコア) が設定され、このスコアによって順序付けが行われます。以下の図に示すように:

Redis を使用してランキング システムを完成させる

#Ordered Set API

以下では、いくつかの Ordered Set API を紹介します。 、ランキング機能を実装するには、これらの API の使用法を知る必要があります。

zAdd

プレイヤー名要素と能力値をスコアとして使用して、プレイヤー 2k の能力値の順序付きリストを設定したいと考えています。 。

カリーの射撃能力は 100、ジェームズは 92、ハーデンは 96、ポールは 97です

sadd は一度に 1 つ以上の要素を追加できます

127.0.0.1:6379[1]> zadd 2kplayer:shoot 100 curry
(integer) 1
127.0.0.1:6379[1]> zadd 2kplayer:shoot 92 james 96 harden 97 paul
(integer) 3
ログイン後にコピー

zIncrBy

ここ 1 か月間、ハーデンは好調で、驚異的な高得点を記録しています。そこで、2k は彼のシュート能力を 2 ポイント向上させることにしました

127.0.0.1:6379[1]> zincrby 2kplayer:shoot 2 harden
"98"
ログイン後にコピー

zRange、zRevRange

次に、トップ 3 プレーヤーが誰であるかを知りたいと思います。

127.0.0.1:6379[1]> zrange 2kplayer:shoot 0 2 withscores
1) "james"
2) "92"
3) "paul"
4) "97"
5) "harden"
6) "98"
ログイン後にコピー

Redis はデフォルトで正の順序を使用し、スコアは小さいものから大きいものへと並べ替えられます。したがって、zRevRange

127.0.0.1:6379[1]> zrevrange 2kplayer:shoot 0 2 withscores
1) "curry"
2) "100"
3) "harden"
4) "98"
5) "paul"
6) "97"
ログイン後にコピー

zUnionStore

2k 能力値には多くの側面があり、スピード、レイアップなど、シュートはそのうちの 1 つにすぎません。 . はすべて能力値の一部です。

127.0.0.1:6379[1]> zadd 2kplayer:speed 99 james 90 paul 90 curry 93 harden 
(integer) 4
ログイン後にコピー

現時点で、プレイヤーの総合的な能力値を知りたい場合は、各項目のスコアを合計する必要があります

127.0.0.1:6379[1]> zunionstore 2kplayer 2 2kplayer:shoot 2kplayer:speed
(integer) 4
127.0.0.1:6379[1]> zrange 2kplayer 0 -1 withscores
1) "paul"
2) "187"
3) "curry"
4) "190"
5) "harden"
6) "191"
7) "james"
8) "191"
ログイン後にコピー

ランキングシステムの実装

シナリオは次のとおりです。毎日多くの人が視聴するビデオ オン デマンド システムです。最も視聴されている動画を表示するリスト機能を備えています。今日のリスト、3日間のリスト、週間ランキング、月間リストに分かれています。

アイデア: まず、日ごとのビデオの再生数を数えてから、今日のリスト、3 日間のリストなどを数えます。

ビデオの再生回数をカウントするための疑似コードは次のとおりです。

// 观看视频
function view ($videoId)
{
    $key = 'video:view:'.date('Y-m-d');  
      
    if (!$redis->exists($key)) {
        $redis->zIncrBy($key, 1, $videoId);
        $redis->expire($key, 86400 * 30);
    }
    
    $redis->zIncrBy($key, 1, $videoId);
}
ログイン後にコピー

Today's Hottest

Today's Hottest があります。注意すべき点が 1 つあります。新しい 1 日が始まったばかりのときは、データが空であるか、ごくわずかである可能性があります。したがって、今日のデータと昨日のデータを組み合わせることができますが、今日のデータの重みを高くします。

今日最も人気のある関数を実装するための疑似コードは次のとおりです:

function todayHot ()
{
    $tokeyKey = 'video:view:'.date('Y_m_d');
    $yesKey = 'video:view:'. date('Y_m_d', time() - 86400);
    $keyUnion = "view:rank:today";
    
    $redis->zUnionStore($keyUnion, [$tokeyKey, $yesKey], [10, 1]);
    // 取前100名
    return $redis->zRevRange($keyUnion, 0, 99);
}
ログイン後にコピー

3 日間のリスト

function threeHot ()
{
    $keyUnion = 'view:rank:three';
    $unionKeys = [];
    
    for ($i=0; $i < 3; $i++) {
        $unionKeys[] = &#39;video:view:&#39;.date(&#39;Y_m_d&#39;, time() - 86400 *$i);
    }
    
    $redis->zUnionStore($keyUnion, $unionKeys);
    return $redis->zRevRange($keyUnion, 0, 99, true);
}
ログイン後にコピー

Weeklyリスト、月別リスト リストなどの考え方は3日リストと同じなのでコードは載せません。

以上がRedis を使用してランキング システムを完成させるの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート