1

私は人のマスターテーブルのようなものを持っています。私のDjangoアプリのすべては、直接または長いfkチェーンを介して、1人以上のPeopleに関連しています。また、私のすべてのモデルには、標準の簿記フィールド「created_at」と「updated_at」があります。主に生のSQL順序付けの目的で、「last_active_at」というフィールドをPersonテーブルに追加したいと思います。

特定の関連モデルを作成または編集すると、それらのオブジェクトの新しいタイムスタンプが生成されます。どういうわけかPerson.'last_active_at'をそれらの値で更新する必要があります。機能的には、これを達成するのはそれほど難しいことではありませんが、アプリへの過度のストレスが心配です。

私の2つの最大の懸念事項は、実際のdbフィールドに制限されていることです(@propertyとしてPersonテーブルに関数を割り当てることはできません)。これらの「アクティビティ」モデルの1つは、一度に大量のデータを散発的に受信する、私が制御できない外部データソース。

私の最初の考えは、post_saveフックを「activity」モデルに追加することでした。それでも私の最善の選択肢のように思えますが、それらについては何も知りません。

私の2番目の考えは、その日のアクティビティを実行し、それらのモデルを夜間に更新するある種のスクリプトを作成することでした。しかし、私の雇用主は「生きている」ストリームです。

私の3番目の考えは、post_saveアルゴリズムを変更して、「updated_at」が個人の「last_active_at」から30分未満であるかどうかを確認し、trueの場合は個人を更新しないことでした。

私の考えはスケーラブルな方向に向かっていますか?私が追求すべき他のアプローチはありますか?

4

1 に答える 1

2

時期尚早の最適化はすべての問題の母であると言われています。最も馬鹿げた実装から始めて(毎回更新する)、次に測定し、必要に応じて、より効率的なものに置き換えます。

まず、のlast_active_atフィールドを更新するメソッドを配置しましょうPerson。そうすれば、すべての更新ロジック自体がここに集中し、後で簡単に変更できます。

シグナルは非常に使いやすいです。関数を宣言してレシーバーとして登録するだけで、シグナルが発信されるたびに実行されます。完全な説明についてはドキュメントを参照してくださいが、次のようになります。

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=RelatedModel)
def my_handler(sender, **kwargs):
    # sender is the object being saved
    person = # Person to be updated
    person.update_activity()

更新自体に関しては、それを行うための最も愚かな方法から始めてください。

def update_activity(self):
    self.last_active_at = now()

次に、それが問題であるかどうかを測定して判断します。それが問題である場合、あなたができることのいくつかは次のとおりです:

  • 再度更新する前に、前回の更新が最近のものかどうかを確認してください。データベースへの読み取りが書き込みよりも高速でない場合は、役に立たない可能性があります。キャッシュを使用する場合は問題ありません。
  • 延期されたプロセスが後で更新できるように、どこかに書き留めておきます。毎日である必要はありません。問題が1秒あたり100回の更新である場合は、スクリプトで10秒ごとまたは1分ごとにデータベースを更新することができます。この手法を使用すると、パフォーマンスと最新性のトレードオフがうまくいく可能性があります。

これらはあなたが提案したものに基づいていますが、正しい選択はあなたが持っている数字の種類に依存します。どのような負荷がかかるか、そのフィールドにどのような反応時間が必要かを判断し、実験します。

于 2012-06-11T15:22:19.237 に答える