web-dev-qa-db-ja.com

集計値の保存と計算

集計値をいつ格納し、いつ計算するかを決定するためのガイドラインまたは経験則はありますか?

たとえば、ユーザーが評価できるウィジェットがあるとします(下のスキーマを参照)。ウィジェットを表示するたびに、Ratingsテーブルから平均ユーザー評価を計算できました。または、Widgetテーブルに平均評価を保存することもできます。これにより、ウィジェットを表示するたびに評価を計算する必要がなくなりますが、ユーザーがウィジェットを評価するたびに平均評価を再計算する必要があります。

Ratings       Widgets
---------     -------
widget_id     widget_id
user_id       name              
rating        avg_rating  <--- The column in question
100
BenV

状況によって異なります。集計値を事前に計算すると、書き込みの負荷が大きくなり、それらを導出すると読み取りが難しくなります

派生値に頻繁にアクセスする場合、事前計算は有効な非正規化手順です。ただし、この場合は、マテリアライズドビュー(ディスクに書き込まれ、トリガーによって親テーブルにリンクされているビュー)を使用することをお勧めします。マテリアライズドビューは、頻繁に要求されるが導出するのが面倒なデータを格納するように設計されており、大量の書き込みと少数の読み取りに役立ちます。

高書き込み、高読み取りのシナリオでは、マテリアライズドビューの効果を模倣するが、リアルタイムではないタスクをバックグラウンドで実行することを検討してください。これは、書き込みと読み取りのパフォーマンスを維持しながら、「十分な」平均を示します。

どのような状況でも、派生列を「通常の」列のように扱うべきではありません。ウィジェットの「ビュー」に表示されるデータがテーブルの別の場所に存在することを確認してください。この質問もデータベース(およびデータベースバージョン)に強く依存しているので、通常のサイズのデータ​​セットおよびマテリアライズドビューに対する集計(適切なインデックスを使用)のパフォーマンステストをお勧めします。

60

基になる数値が変更/更新される頻度に関連して、値を計算/表示する必要がある頻度。

したがって、1時間に1回しか変更されない値を表示する、1日に1万ヒットのWebサイトがある場合は、基になる値が変更されたときにデータベーストリガーである可能性がありますが、それを計算します。

統計情報が秒単位で変化するところに行って統計情報を確認するツールがあっても、アクセスできるのは3人だけで、1日2回しか確認しない場合は、計算する可能性が高くなります。その場で。 (最初に古いデータがあったとしても大したことではないと計算するのに数分かかる場合を除いて...そして、上司はcronから1時間ごとに生成するように言っているので、彼がそれを見たいときに待つことです。)

11
Joe

StaleWidgetsテーブルを「無効な」(再計算される)ウィジェットのキューとして使用します。これらの値を再計算できる他のスレッド(非同期)タスクを使用してください。再計算の期間または瞬間は、システム要件によって異なります。

  • 読んだだけで
  • 月末に
  • 一日の始めにあるユーザーのために
  • ...
4
garik

計算がそれほど面倒ではなく、複雑な計算と頻繁な更新があり、計算されたデータを格納でき、再計算が必要かどうかを格納する追加の列(ブール値)よりも読み取りが頻繁でない場合は、オンザフライで計算することをお勧めします。例えば再計算を行う必要がある場合は常にこの列をtrueに設定しますが、再計算は行わず、再計算を行う場合はこの列をfalseに設定します(これは、計算値が最新で古くないことを表します)。

これにより、毎回再計算する必要がなくなり、列の値を読み取って再計算する必要がある場合にのみ計算が行われます。この方法で、多くの再計算を節約できます。

2
techExplorer

特にケースについては、すべての評価を追加して合計で割って平均を求める必要がない別のソリューションがあります。代わりに、レビューの合計を含む他のフィールドを使用できます。したがって、評価を追加するたびに、(avg_rating×total + new_rating)/合計を使用して新しい平均を計算します。これは、集計よりもはるかに高速であり、ディスクの読み取りを減らします。すべての評価値にアクセスする必要はありません。同様のソリューションが他のケースに適用される場合があります。

これの欠点は、それが酸性のトランザクションではないため、古い評価で終わる可能性があることです。しかし、それでもデータベースでトリガーを使用することでそれを解決できます。もう1つの問題は、データベースが正規化されなくなったことですが、パフォーマンスと引き換えにデータを非正規化することを恐れないでください。

2
Adrian Martinez