検索
ホームページデータベースRedisRedis がランキングと時間による同一ポイントソート機能を実装する方法の詳細な例

推奨学習: Redis ビデオ チュートリアル

日々の開発では、ユーザー スコアなどを計算する必要に遭遇することがよくあります。たとえば、ゲームでは戦闘効率をランク付けする必要があり、チーム活動では各チームの貢献値をランク付けする必要があり、WeChat では各友達の歩数をランク付けする必要があります。この場合、一般に、Redis の順序が選択されます。コレクションには、ランキングのニーズを満たすためにユーザーのスコアが保存されます。ただし、シナリオごとのランキング方法も若干異なります。以下は、私の日々の開発に基づいた要約です。

要件: チーム アクティビティにおける各チームの貢献値をランク付けします。

同一のポイントは考慮されません

Redis のソート セットは、文字列型の順序付きセットです。セットのメンバーは一意であるため、セット内に重複したデータが存在することはできません。

各要素は double 型のスコアに関連付けられます。 Redis はスコアを使用して、コレクションのメンバーを小さいものから大きいものまで並べ替えます。

順序付きセットのメンバーは一意ですが、スコアは繰り返すことができます。

同じポイントを持つ状況を無視して、ランキング リストを実装します:

// 准备数据,其中value为每个队伍的ID,score为队伍的贡献值
> zadd z1 5 a 6 b 1 c 2 d 10 e
(integer) 5

// 分页查询排行榜所有的队伍和贡献值,要使用zrevrange,而不是zrange,贡献值越大越排在前面
> zrevrange z1 0 2 withscores
1) "e"
2) "10"
3) "b"
4) "6"
5) "a"
6) "5"

// 增加某个队伍的贡献值
> zincrby z1 3 d
"5"
> zincrby z1 4 c
"5"

// 查询排行榜所有的队伍
> zrevrange z1 0 -1 withscores
 1) "e"
 2) "10"
 3) "b"
 4) "6"
 5) "d"
 6) "5"
 7) "c"
 8) "5"
 9) "a"
10) "5"

// 查询某个队伍的排名
> zrevrank z1 d
(integer) 2

Redis のデフォルトの実装では、同じスコアを持つメンバーが辞書順 (09、AZ、上記で使用しているa~z)はzrevrangeなので逆順となり、同じスコアでのソートは時間優先でソートできません。

同じポイントは時間順にソートされ、ランキングは一意になります

上記の実装では、2 つのチームの貢献値が同じ、つまりポイント値が同じである場合、時間に基づいてランク付けすることはできません。

したがって、 スコア = 貢献値のタイムスタンプ を設計する必要があります。スコアが高い人が最初にランクされます。最後に、スコアに基づいて貢献値を分析する必要があります。

設計 1

スコア値の保存には整数を使用します。redis のスコア自体は double 型であり、正確に保存できる最大整数は 2^53=9007199254740992 (16 ビット) です。 )。ミリ秒まで正確なタイムスタンプには 13 桁が必要で、ストレージ寄与値には 3 桁のみが残ります。現在、時刻が秒まで正確な場合、必要なのは 10 桁のみで、寄与値には 6 桁が残ります。

全体的な設計: 上位 3 ビットは寄与値を表し、下位 13 ビットはタイムスタンプを表します。

単純にスコア構造をまとめると、貢献値 * 10^13 タイムスタンプ になります。スコアが大きいほどスコアは近くなり、タイムスタンプが小さいほどスコアは近くなります。このように、2つの判定ルールは逆のものもあり、単純に両者を組み合わせてスコア化することはできません。

しかし、逆に考えて、同じ十分に大きな数値 Integer.MAX からタイムスタンプを減算することもできます。タイムスタンプが小さいほど、得られる差が大きくなるため、スコアの構造を変更できます。値に貢献します。 to: * 10^13 (Integer.MAX-timestamp) これにより、ニーズを満たすことができます。

設計2

redisのスコア値はdouble型なので、整数部分に貢献値を格納し、小数部分にタイムスタンプを格納し、最大値を使用することができます。同じタイムスタンプの部分からそれを減算します。

このようにして、全体的な設計は次のようになります: スコア = 貢献値 (Integer.MAX-タイムスタンプ) * 10^-13

欠点: スコア値は変数を使用して計算されるため、チームに貢献値を追加する場合、以前のzincrbyを使用してスコア値を変更することはできず、同時条件でチームに貢献値を追加すると、スコアが不正確になります。価値観。

エラー状況シミュレーション:

チーム A の現在の貢献値が 10 であるとします。チーム A のプレイヤー X がチームに貢献値を 1 追加し、プログラムでスコアが計算されます。チーム A のプレーヤー Y はチームに貢献値 1 を追加し、スコアはプログラムで 11 になるように計算されます。yyy チーム A のプレーヤー X が redis の zadd コマンドを呼び出して、チームの貢献値を 11 に設定します。 .xxx チーム A のプレイヤー Y が redis の zadd コマンドを呼び出します。 チームの貢献値を 11.yyy に設定します。 最終的に、チーム A の貢献値は 11 と計算されます。貢献値を増やす操作のアトミック性は保証できません。

現時点では、lua スクリプトを使用して、貢献値の計算と設定の 2 つの操作のアトミック性を確保する必要があります。

// 其中KEYS[1]为排行榜key,KEYS[2]为队伍ID
// 其中ARGV[1]为增加的贡献值,ARGV[2]为Integer.MAX-时间戳
local score = redis.call('zscore', KEYS[1], KEYS[2]) 
if not(score) then
	score=0 
end 
score=math.floor(score) + tonumber(ARGV[1]) + tonumber(ARGV[2]) 
redis.call('zadd', KEYS[1], score, KEYS[2]) return 1

redis では time 関数を使用できないため、 (Integer.MAX - タイムスタンプ) * 10^-13 の部分は、スクリプトの外のプログラムによって計算されて渡されます。

ランキング リストのページングやチームのランキングのクエリなどの機能には、引き続き上記のコマンドを使用できます。

同ポイントを時間順に並べた同順位ランキング

いわゆる同順位ランキングとは、順位状況が同じ順位のランキングです。

期待される結果は次のとおりです:

#b992c992##de

当然现实中也有排名不跳过的情况,我这里考虑的是排名跳过的情况。

redis中score的设计还是采用上面的分数=贡献值 + (Integer.MAX-时间戳) * 10^-13,只是在查询排名时需要进行计算。

比如要查上表中队伍b的排名,思路如下:

  • 首先查到队伍b的score
  • 再查到跟队伍b的score的整数部分相同(也就是贡献值一样),排在第一个的队伍的value(队伍ID)
  • 根据上一步得到的队伍ID查询此队伍的排名就是队伍b的排名

使用命令实现上面的步骤如下:

> zscore 排行榜key teamId
> zrevrangebyscore(排行榜key, 上一步得到的score+1, 上一步得到的score, limit, 0 , 1)
> zrevrank(排行榜key, 上一步得到的teamId)

为了性能考虑,可以使用下面的脚本一次查出来:

// KEYS[1]表示排行榜key
// KEYS[2]表示要查询的队伍的ID
local rank = 0 
local score = redis.call('zscore', KEYS[1], KEYS[2]) 
if not(score) then
    score=0 
else 
    score=math.floor(score) 
    local firstScore = redis.call('zrevrangebyscore', KEYS[1], score+1, score, 'limit', 0, 1) 
    rank=redis.call('zrevrank', KEYS[1], firstScore[1]) 
end 
return {score,rank}

下面附上分页查询排行榜的脚本,假如一页10条,不用下面的脚本需要查询10次上面的脚本,如果连上面的脚本都没有使用的话就要查询30次redis。

// 排行榜key
// ARGV[1]分页起始偏移
// ARGV[2]分页结束偏移
local list = redis.call('zrevrange', KEYS[1], ARGV[1], ARGV[2], 'withscores') 
local result={} 
local i = 1 
for k,v in pairs(list) do 
    if k%2 == 0 then 
        local teamId = list[k-1] 
        local score = math.floor(v) 
        local firstScore = redis.call('zrevrangebyscore', KEYS[1], score+1, score, 'limit', 0, 1) 
        local rank=redis.call('zrevrank', KEYS[1], firstScore[1]) 
        local l = {teamId=teamId, contributionValue=score, teamRank=rank+1} 
        result[i] = l i = i + 1 
    end 
end 
return cjson.encode(result)

此脚本使用了cjson库,返回的是一个json。

推荐学习:Redis视频教程

チーム ID 貢献度 ランキング
a 100 1
88 4
87 5

以上がRedis がランキングと時間による同一ポイントソート機能を実装する方法の詳細な例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は脚本之家で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
RedisはSQLまたはNOSQLデータベースですか?答えが説明しましたRedisはSQLまたはNOSQLデータベースですか?答えが説明しましたApr 18, 2025 am 12:11 AM

redisisclassifiedsaNosqldatabasebasesakey-valuedataModelinsteaded ofthetraditionaldatabasemodel.itoffersspeedand andffficability、makingidealforreal-timeaplications andcaching、butmaynotbesbesutable fors cenariois requiring datientiantientioniity

Redis:アプリケーションのパフォーマンスとスケーラビリティの向上Redis:アプリケーションのパフォーマンスとスケーラビリティの向上Apr 17, 2025 am 12:16 AM

Redisは、データをキャッシュし、分散ロックとデータの持続性を実装することにより、アプリケーションのパフォーマンスとスケーラビリティを向上させます。 1)キャッシュデータ:Redisを使用して頻繁にアクセスしたデータをキャッシュして、データアクセス速度を向上させます。 2)分散ロック:Redisを使用して分散ロックを実装して、分散環境での操作のセキュリティを確保します。 3)データの持続性:データの損失を防ぐために、RDBおよびAOFメカニズムを介してデータセキュリティを確保します。

Redis:データモデルと構造の調査Redis:データモデルと構造の調査Apr 16, 2025 am 12:09 AM

Redisのデータモデルと構造には、5つの主要なタイプが含まれます。1。文字列:テキストまたはバイナリデータの保存に使用され、原子操作をサポートします。 2。リスト:キューとスタックに適した注文された要素コレクション。 3.セット:順序付けられていない一意の要素セット、セット操作をサポートします。 4。注文セット(sortedset):ランキングに適したスコアを持つ一意の要素セット。 5。ハッシュテーブル(ハッシュ):オブジェクトの保存に適したキー価値ペアのコレクション。

Redis:データベースアプローチの分類Redis:データベースアプローチの分類Apr 15, 2025 am 12:06 AM

Redisのデータベースメソッドには、メモリ内データベースとキー価値ストレージが含まれます。 1)Redisはデータをメモリに保存し、速く読み取り、書き込みます。 2)キー価値のペアを使用してデータを保存し、キャッシュやNOSQLデータベースに適したリスト、コレクション、ハッシュテーブル、注文コレクションなどの複雑なデータ構造をサポートします。

なぜRedisを使用するのですか?利点と利点なぜRedisを使用するのですか?利点と利点Apr 14, 2025 am 12:07 AM

Redisは、高速パフォーマンス、リッチデータ構造、高可用性とスケーラビリティ、持続性能力、幅広いエコシステムサポートを提供するため、強力なデータベースソリューションです。 1)非常に速いパフォーマンス:Redisのデータはメモリに保存され、非常に速い読み取り速度と書き込み速度が高く、高い並行性と低レイテンシアプリケーションに適しています。 2)豊富なデータ構造:さまざまなシナリオに適したリスト、コレクションなど、複数のデータ型をサポートします。 3)高可用性とスケーラビリティ:マスタースレーブの複製とクラスターモードをサポートして、高可用性と水平スケーラビリティを実現します。 4)持続性とデータセキュリティ:データの整合性と信頼性を確保するために、データの持続性がRDBとAOFを通じて達成されます。 5)幅広い生態系とコミュニティのサポート:巨大なエコシステムとアクティブなコミュニティにより、

NOSQLの理解:Redisの重要な機能NOSQLの理解:Redisの重要な機能Apr 13, 2025 am 12:17 AM

Redisの主な機能には、速度、柔軟性、豊富なデータ構造のサポートが含まれます。 1)速度:Redisはメモリ内データベースであり、読み取り操作はほとんど瞬間的で、キャッシュとセッション管理に適しています。 2)柔軟性:複雑なデータ処理に適した文字列、リスト、コレクションなど、複数のデータ構造をサポートします。 3)データ構造のサポート:さまざまなビジネスニーズに適した文字列、リスト、コレクション、ハッシュテーブルなどを提供します。

Redis:主要な機能を特定しますRedis:主要な機能を特定しますApr 12, 2025 am 12:01 AM

Redisのコア関数は、高性能のメモリ内データストレージおよび処理システムです。 1)高速データアクセス:Redisはデータをメモリに保存し、マイクロ秒レベルの読み取り速度と書き込み速度を提供します。 2)豊富なデータ構造:文字列、リスト、コレクションなどをサポートし、さまざまなアプリケーションシナリオに適応します。 3)永続性:RDBとAOFを介してディスクにデータを持続します。 4)サブスクリプションを公開:メッセージキューまたはリアルタイム通信システムで使用できます。

Redis:一般的なデータ構造のガイドRedis:一般的なデータ構造のガイドApr 11, 2025 am 12:04 AM

Redisは、次のようなさまざまなデータ構造をサポートしています。1。文字列、単一価値データの保存に適しています。 2。キューやスタックに適したリスト。 3.非重複データの保存に使用されるセット。 4。ランキングリストと優先キューに適した注文セット。 5。オブジェクトまたは構造化されたデータの保存に適したハッシュテーブル。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター