私の問題の例を挙げましょう。usersというテーブルとpaymentというテーブルがあるとします。ユーザーの合計残高を計算するには、クエリを使用して特定の日付以降のすべての支払いを取得し、結果をしばらくキャッシュします。
ただし、この性質上、 users テーブルに列を呼び出して、キャッシュの有効期限が切れたら、別のクエリを使用して支払いを収集するのは良い考えではないかと思っていましたbalance
が、より短い時間と次に、この金額を列にあるものに追加しbalance
ますか?
私の問題の例を挙げましょう。usersというテーブルとpaymentというテーブルがあるとします。ユーザーの合計残高を計算するには、クエリを使用して特定の日付以降のすべての支払いを取得し、結果をしばらくキャッシュします。
ただし、この性質上、 users テーブルに列を呼び出して、キャッシュの有効期限が切れたら、別のクエリを使用して支払いを収集するのは良い考えではないかと思っていましたbalance
が、より短い時間と次に、この金額を列にあるものに追加しbalance
ますか?
ユーザーの合計残高を計算するには、
ユーザーの現在の残高を常に含む追加のテーブルを作成できます。ユーザーに新しい支払いが追加された場合、その列も更新する必要があります。支払いの追加と合計残高の更新が一致するようにトランザクションを実行します。
これをさらに差別化する必要がある場合は、ユーザー関係の横に、計算を行うために必要な間隔を表す日付列を保持できます。たとえば、過去のビューを表示できる週番号または月番号。
さらに柔軟性が必要な場合は、しばらくしてから既存の支払いを合計値に圧縮し、それをユーザー関連で日付列を保持するバランス テーブルに格納できます。
次に、まだ圧縮/圧縮されていない日付に対して「リアルタイム」である支払いのテーブルと UNION できます。次に、集計関数を使用して合計残高を合計します。最近のデータをより詳細に保持する必要がある場合、統計値を保持するだけで、しばらくしてからデータストアから移動できます。
一般に、これらの種類の「事前計算された」値では、データに関係するモデルの保存時にそれらを保存/更新するのが最も簡単な方法であることがわかりました
つまり、新しい支払いが保存されるたびに合計残高を更新します。そうすれば、データベースとデータが常に同期していることを保証できます
事前計算は、mysql トリガーまたは Gearman などのバックグラウンド タスクのいずれかです。
しかし、あなた自身の質問が示唆しているように、残高の何らかの増分ロールアップを行いたい場合は、月単位または固定の日付範囲で行うことをお勧めします。これは、支払いが古い月に表示される可能性がある場合に、支払いの遡及またはそのようなものがない場合に機能します。
新しい月の初めに、支払いアグリゲーターを実行します。バム、今は毎月のテーブルを合計するだけです。
それはすべて、処理する必要があるデータの量に大きく依存します。しかし、繰り返しになりますが、データの一貫性は速度よりもはるかに重要であり、いつでもサーバーを追加購入できます.