ホームページ >バックエンド開発 >PHPチュートリアル >ユーザー参加記録ストレージの進化_PHPチュートリアル
このようなアプリケーション シナリオがあります。ユーザーは 2 つの連続した操作 A と B を実行します。操作 A が完了する前に操作 B がトリガーされると、操作 A が完了する必要があることが表示されます。まず、操作 B を実行するには、操作 A が実行されたかどうかをクエリする必要があります。ここで生じる問題は、ユーザーの参加記録を記録し、ユーザーと操作に対するクエリ方法を提供することです。データの量が異なれば、ストレージ ソリューションも大きく異なります。データの増加に伴い、ソリューションも進化し続けます。
1. データ量が少なく、ユーザーの操作動作が固定されています:
ストレージ: MySQL
プラン: UID をキーとして使用し、1 行に 1 ユーザーを使用し、各ユーザーに含まれるユーザーを列として保存します。 、UID=100、固定ストレージはオペレーション A とオペレーション B、テーブル構造は大まかに次のとおりです:
table_operation
uid Operation_a Operation_b
100 1 1
ユーザーが A または B に参加しているかどうかをクエリしたい場合は、SQL を使用します。直接: SELECT * FROM table_operation WHERE uid=100 AND action_a=1 目標は達成できます。
問題: ユーザー操作が固定されており、拡張が困難である場合、フィールドを追加するか、テーブル ストレージを増やす必要があります。フィールドを追加する方法は、特定のデータ レベル (100 万など) 未満で実行可能です。動作時間が重要でない場合、テーブル ストレージ ソリューションを追加するパフォーマンスは非常に優れています。
2. データ量が少なく、ユーザー操作の動作が固定されていない:
シナリオ 1 と比較して、現在のシナリオでは uid 変数に加えてユーザー操作変数が追加されています。つまり、2 つの変数に注意する必要があります。 : ユーザーとユーザーの操作。
ストレージ: MySQL
オプション 1: オペレーション テーブルを追加し、オペレーション ID を生成し、uid と oid をユーザー オペレーション動作テーブルに保存します。ユーザーが新しい操作を実行すると、操作動作テーブルにレコードが挿入されます。テーブル構造はおおよそ次のとおりです。
table_operation_info
oid name
1 Operation_a
2 Operation_b
table_operation
uid oid
1 1
1 2
ユーザー 1 が操作 A を実行したかどうかをクエリする必要がある場合は、SQL を使用します。 SELECT * FROM table_operation WHERE oid=1 AND oid=1。
問題: ユーザーの操作動作が大きい場合、ユーザーの操作動作が急速に増加し、MySQL が 1 つのテーブルをロードできなくなる可能性があります。解決策については、次のシナリオで説明します。
3. 大量のデータ、ユーザーの動作の修正
ストレージ: MySQL
解決策: シナリオ 1 と比較すると、現在のシナリオはデータ量が大きく、MySQL では処理できないという点で異なります。単一のテーブルをロードします。このソリューションはこの問題を解決します。単一のテーブルが大きすぎる場合、最もコスト効率の高い方法は、別のテーブルを使用することです。現在のシーンの変数は uid なので、uid に基づいてテーブルをレベルごとに分割するだけで済みます。
4. データ量が多く、ユーザーの動作が固定されていない
ストレージ: MySQL
スキーム 1: このスキームは、ユーザーの操作動作を分類できる状況に適用されます。つまり、2 つのテーブル分割操作が追加されます。シナリオ 1 の基礎。操作に従って、行動カテゴリごとのテーブルとユーザーごとのテーブルが作成されます。現在のソリューションでは、操作動作とユーザーという 2 つの変数を扱う必要があります。 2 つのテーブル分割は、それぞれこれら 2 つの変数に対応しており、ビジネス ルールに従ってテーブル分割操作が実行され、データ量を削減するためにユーザー ID に応じてデータが水平に分割されます。
オプション 2: このソリューションは、シナリオ 2 のソリューションに基づいた完全な水平テーブル分割操作であり、ユーザー レベルに応じて分割されます。
5. データ量が非常に大きいです
ストレージ: MySQL
オプション 1: 現時点では、1 つのデータベースではニーズを満たすことができません。実際のニーズに応じて、異なるデータベースを異なるマシンに配置することを検討できます。
オプション 2: サブデータベースとサブテーブルに基づいて、それをビット単位で保存します。操作が実行されたかどうかはステータス (0、1 ステータス) であるため、1 ビットを使用して保存できます。 64 ビットには 64 個の動作動作マーカーを保存できます。
その他のストレージ
キー値データベース
実際には、単純な k-v データベースで多くのリレーショナル データベース機能を必要とせず、より少ない速度で実行できます。
メモリベースを選択するか非メモリベースを選択するかに関係なく (実際のニーズに応じて選択することも、ホットデータをメモリに保存し、サイレントデータを非メモリに保存することもできます)、それを保存するのに十分なスペースがあると仮定します。
オプション 1:
uid+oid をキーとして使用すると、値にステータスを保存したり、参加するかどうか (0 と 1) だけを保存したりできますが、特にデータ量が多すぎる場合、キーが多すぎます。 uid の数 *oid の数は、想像できないほど大きいかもしれません。
オプション 2:
一般的に、ユーザーの操作行動に関するデータの量はユーザーのサイズよりも完全に小さく、ユーザーの操作行動に関するデータは制御可能です。キーの数を減らしたい場合は、oid + ユーザー パーティション インデックス ID をキーとして使用できます。ここでのいわゆるユーザー パーティション インデックスとは、ユーザーを特定の数の領域に分割することを指し、すべてのユーザーがこの間隔で記録されます。 、10000 が間隔である場合、uid 1 ~ 9999 のユーザーは間隔 0 に分割されます。ここで、1 と 0 は、ユーザーがこの操作を実行したかどうかを格納するために使用できます。キーに対応する値は、10000 を格納するように初期化されます。 0秒。 uid=100のユーザーが操作を行うと、100番目の0が1に設定されます。
オプション 3:
オプション 2 に基づいて、10,000 個の 0 を 10,000 個の 01 ビットに変換すると、1 つのビットが 50 ビットを格納すると仮定すると、合計で 200 個だけが必要になります。
オプション 4:
ユーザーの数が非常に多い場合、ほとんどのユーザーが特定の操作に参加しない可能性があります。解決策 3 に基づいて、単純なスパース行列圧縮を追加し、保存されるときのみインデックスを各ストレージ ビットに追加します。格納された値が 0 ではない場合。
オプション 5:
まだ考えていません。共有を楽しみにしています
概要
•データ量が増加するにつれて、テーブルを分割するのが一般的な考え方です。テーブルを処理できない場合は、分割します。テーブルを分割し、ライブラリが処理できない場合はテーブルを分割し、1 台のマシンで処理できない場合はマシンを追加します。
•さまざまなストレージメディアを選択するときは、コストと需要を考慮する必要があり、すべての選択はバランスの結果です。
•スペースを節約し、ビットごとに保管します。
•時期尚早に最適化しないでください。