Railsを使用して概要データを絶えず再計算することを避けるにはどうすればよいですか?
-
28-10-2019 - |
質問
スタックオーバーフロープロファイルページ(総訪問、バッジの数など)とは異なり、ユーザーの統計を備えたサイドバーを備えたユーザープロファイルページがあります。
問題は、現在、データベースにヒットし、すべてのリクエストでこれらの統計を計算していることです。フラグメントキャッシュを実装してこれを削減することができますが、このタイプのものを処理するより良い方法はありますか?
データベースに集約された要約データを保存すると、問題が発生する可能性があるようです(つまり、矛盾)。
解決
この情報は、以下を再計算する代わりに、データベースに保存できます。
- カウンターキャッシング
- カスタムコールバック
カウンターキャッシング
例として、バッジの数を測定する場合、データベースフィールドを作成できます User
呼び出されました badges_count
, 、次に、バッジモデルで、持っています belongs_to :user, :counter_cache => true
. 。これで、バッジの数が変更されるたびに、で新しい計算なしでカウントにアクセスできます @user.badges_count
.
基本的な実装: http://asciicasts.com/episodes/23-counter-cache-column
カスタムコールバック
単純なカウントよりも複雑な動作を測定するフィールドがあるとしましょう。この場合、特定のアクションが使用されるたびにフィールドを更新するコールバックを実装するだけです before_save
, after_save
, before_create
, 、など
矛盾についての懸念
データベースにデータを保存することは、間違っている場合にのみ一貫性がありません。統計を更新できる有限数のパスがあり、使用しているフィールドの更新ですべてのパスがカバーされていることを確認する必要があります。 Railsはcounter_cachingであなたのためにそれをします、そして、あなたがカスタムコールバックを使用する場合、またはいくつかの異常な状況がある場合、あなたは自分でそれをする必要があります。
他のヒント
この質問のように隠されたdivを使用できます(隠されたDivを使用してデータをキャッシュします)。キャッシュするデータの量に応じて、これは良い解決策かもしれません。