2012-06-11 72 views
1

我有一些人的主表。我的Django應用程序中的所有內容都與一個或多個人有關,無論是直接還是通過長時間連鎖。另外,我所有的模型都有標準的簿記字段'created_at'和'updated_at'。我想在我的Person表上添加一個名爲'last_active_at'的字段,主要用於原始的sql排序目的。Django模型:通過相關模型跟蹤活動?

創建或編輯某些相關模型會爲這些對象生成新的時間戳。我需要以某種方式更新Person.'last_active_at'這些值。在功能上,這並不難完成,但我擔心應用程序會產生過度的壓力。

我最關心的兩個問題是,我被限制在一個真正的db字段中 - 我無法將一個函數作爲@屬性分配給Person表,並且這些「活動」模型中的一個接收並處理來自外部數據源的新實例我無法控制,一次接收大量數據。

我的第一個想法是爲'活動'模型添加post_save掛鉤。仍然看起來像我最好的選擇,但我對他們一無所知,他們多麼難以擊中分貝,等等。

我的第二個想法是寫一些腳本,通過一天的活動,並在夜間更新這些模型。雖然我的僱主是'生活'流。

我的第三個想法是修改post_save算法,以檢查'updated_at'是否距離Person的'last_active_at'小於半小時,如果爲true,則不更新該人員。

我的想法是否趨於可擴展的方向?我應該追求其他方法嗎?

回答

2

據說過早優化是所有問題的母親。你應該從最笨的實現開始(每次更新它),然後測量並且 - 如果需要的話 - 用更有效率的東西替換它。

首先,讓我們來更新last_active_at字段的方法Person。這樣,所有更新邏輯本身都集中在這裏,我們可以在以後輕鬆修改它。

這些信號非常易於使用:它只是聲明一個函數並將其註冊爲接收器,並且每次發出信號時都會運行。爲全面解釋見the documentation,但這裏是它可能是什麼樣子:

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() 

然後測量並確定它是否有問題。如果出現問題,您可以執行的一些操作如下:

  • 在再次更新之前檢查先前的更新是否是最近的。如果讀取數據庫的速度不及寫入速度快,則可能無用。如果您使用緩存,則不是問題。
  • 寫下某個地方延遲的過程稍後更新。不需要每天:如果問題是每秒有100次更新,則可以讓腳本每隔10秒或每分鐘更新一次數據庫。你可以使用這種技術找到一個很好的性能/ uptodatiness折衷。

這些只是一些雖然基於你的建議,但正確的選擇取決於你有什麼樣的數字。確定你將擁有什麼樣的負載,該領域需要什麼樣的反應時間,以及實驗。

+0

正在運行memcached ...需要appx半小時的響應時間...聽起來像我需要推動prod並獲得玩具的負載!謝謝。 –

+0

什麼可能是一些好工具來衡量這種事情? –

+0

您可以輕鬆使用https://docs.djangoproject.com/en/1.2/faq/models/#faq-see-raw-sql-queries來測量查詢所需的時間。對於更高級的配置文件,django-profiling看起來像一個不錯的工具,但可能還有其他的。 – madjar