2011-12-13 85 views
0

我有兩個型號 -在Django中將數據從一個表複製到另一個表的最快方法是什麼?

ChatCurrent - (存儲消息當前活動的聊天記錄)
ChatArchive - (的存檔消息已經結束了聊天記錄)我做

原因這是爲了使ChatCurrent表總是有最小數量的條目,使查詢錶快速(我不知道這是否工作,請讓我知道如果我有這個錯誤

所以我基本上想要將ChatCurrent中的數據複製(剪切)到ChatArchive模型。什麼是最快的方式來做到這一點。從我在線閱讀的內容來看,似乎我可能不得不執行一個原始的SQL查詢,如果你願意,甚至可以說出我會很感激的查詢。

其他詳細信息 - 這兩個模型具有相同的模式。

回答

3

我的看法是,他們的今天沒有理由denormalize database以這種方式來提高性能。索引或分區+索引應該足夠了

此外,如果是,語義的原因,你更喜歡有兩個表(型號),如:聊天和ChatHistory(或ChatCurrent和ChatActive)如你說的和Django的管理它,我的事情,正確的方法保持一致性爲在ChatCurrent中創建ToArchive()方法。此方法會將聊天條目移至歷史聊天模式。您可以在後臺模式下執行此操作,然後您可以在celery進程中線程交換,這樣在線用戶可以避免等待請求。進入芹菜過程最快的方法是複製數據是raw sql。請記住,您可以將sql封裝到存儲過程中。

編輯,包括回覆您的評論

您可以執行ChatCurrent.ToArchive()在ChatCurrent.save()方法:

class ChatCurrent(model.Model): 
    closed=models.BooleanField() 

    def save(self, *args, **kwargs): 
     super(Model, self).save(*args, **kwargs) 
     if self.closed: 
      self.ToArchive() 

    def ToArchive(self): 
     from django.db import connection, transaction 
     cursor = connection.cursor()    
     cursor.execute("insert into blah blah") 
     transaction.commit_unless_managed() 
     #self.delete() #if needed (perhaps deleted on raw sql) 
+0

但我想在聊天結束時複製數據。這是其中一種觀點引發的。 – Sussagittikasusa

+0

@Sussagittikasusa,在帖子中回覆。這是你說的嗎? – danihp

+0

是的,謝謝,我得到了這個解決方案。那麼你說的是什麼分區,我不完全明白如何在不把它們分成兩張表的情況下做到這一點。 – Sussagittikasusa

1

嘗試這樣:

INSERT INTO "ChatArchive" ("column1", "column2", ...) 
SELECT "column1", "column2", ... 
FROM "ChatCurrent" WHERE yourCondition; 

,並不僅僅是

DELETE FROM "ChatCurrent" WHERE yourCondition; 
2

你正在試圖做的事情是表分區。 大多數數據庫都支持此功能,無需手動預訂。

分區還會產生比手動將數據部分移動到不同表格更好的結果。通過使用分區,您可以避免: - 數據不一致。這很容易引入,因爲您將批量移動記錄,然後從源表中刪除大量記錄。很容易犯一個錯誤,只複製一部分數據。 - 性能下降 - 移動數據和相關的事務開銷通常會忽略您通過減小ChatCurrent表的大小而獲得的任何好處。

爲了一個真正快速破敗。表分區允許您告訴數據庫部分數據一起存儲和檢索,這會顯着加快查詢速度,因爲數據庫知道它只需查看數據集的特定部分。示例:從當天,最後一小時,上個月等開始聊天。您還可以將每個分區存儲在不同的驅動器上,這樣您就可以將當前的聊天記錄保留在快速SSD驅動器上,並在常規較慢的磁盤上保留您的歷史記錄。

請參閱數據庫手冊以瞭解有關它如何處理分區的詳細信息。

PostgreSQL的

例子:http://www.postgresql.org/docs/current/static/ddl-partitioning.html

分區是指分裂是什麼邏輯上的一個大表分成更小的物理塊。分區可以提供幾個好處:

  • 查詢性能可以顯着地在某些情況下得到改善,尤其是當最表的頻繁訪問的行的是在一個單一的分區或小數目的分區。分區替代了領先的索引列,減少了索引大小,並使得索引中大量使用的部分更適合內存。

  • 當查詢或更新訪問單個分區的很大比例時,可以通過利用該分區的順序掃描而不是使用索引來優化性能,並且散佈整個表的隨機訪問讀取。

  • 批量加載和刪除可以通過添加或刪除分區來完成,如果該需求計劃在分區設計中。 ALTER TABLE NO INHERIT和DROP TABLE都比批量操作要快得多。這些命令也完全避免了批量DELETE導致的VACUUM開銷。

  • 很少使用的數據可以遷移到更便宜和更慢的存儲介質。

0

按照上述方案,不要複製過度。

如果您確實想要查詢兩個單獨的表,請將您的聊天記錄存儲在單個表中(並且首選使用此處提及的所有數據庫技術),然後創建一個Current和Archive表,其對象只需指向聊天對象/

0
def copyRecord(self,recordId): 
    emailDetail=EmailDetail.objects.get(id=recordId) 
    copyEmailDetail= CopyEmailDetail() 
    for field in emailDetail.__dict__.keys(): 
     copyEmailDetail.__dict__[field] = emailDetail.__dict__[field] 
    copyEmailDetail.save() 
    logger.info("Record Copied %d"%copyEmailDetail.id) 
相關問題