2010-06-11 23 views
1

假設你有兩種類型的消息和聯繫人,它們與Message的 db.ListProperty關鍵字相關。用戶創建消息,將某些聯繫人添加爲收件人,並通過電子郵件發送消息。之後,用戶 刪除作爲 消息收件人的聯繫人實體之一。我們的應用程序應刪除相應的聯繫人 實體,但我們希望保留爲用戶記錄發送的 消息的原始收件人列表。實質上,我們希望消息實體在發送時擁有一個 快照。如果我們天真 刪除聯繫人實體,但我們失去了快照完整性;如果不是, 我們剩下一個無效的密鑰。應用程序引擎:你將如何...快照實體

您將如何處理這種情況, 要麼在控制器邏輯或模型的變化?


    class User(db.Model): 
     email = db.EmailProperty(required=True) 

    class Contact(db.Model): 
     email = db.EmailProperty(required=True) 
     user = db.ReferenceProperty(User, collection_name='contacts') 

    class Message(db.Model): 
     recipients = db.ListProperty(db.Key) # contacts 
     sender = db.ReferenceProperty(User, collection_name='messages') 
     body = db.TextProperty() 
     is_emailed = db.BooleanProperty(default=False) 

回答

2

我想補充一個布爾字段「已刪除」(或東西spiffier,如日期和刪除的時間)的聯繫模式 - 使接觸從未物理刪除,而只是「邏輯」當該字段被設置時被刪除。 (這也可以讓你提供其他很酷的功能,如「顯示我現在刪除的舊聯繫人」,「取消刪除」功能等,如果你願意的話)。

這是在維護歷史完整性(和/或類似需求,如「可審計性」)所需的所有存儲系統中的常用方法。

如果大量的邏輯刪除的實體可能會損害系統性能,那麼經典的選擇是擁有一個單獨的,相同的模型「DeletedContacts」,但外鍵約束需要更多的工作。如果需要外鍵完整性(但只需使用鍵,就像你在做的那樣,不需要額外的工作),則消息類必須同時具有recipientsdeleted_recipients的範圍

我懷疑普通用戶會刪除如此大比例的聯繫人,以保證最後一段中解釋的優化,所以在這種情況下,我會使用簡單的「已刪除」字段。

+0

謝謝亞歷克斯! 「軟刪除」策略就是我們所實施的(但我們錯過了這個令人震驚的選擇)。我很高興聽到它得到你的印章! :) 現在我正在考慮更豐富的狀態(例如,is_deleted,is_confirmed,is_preferred等),以及如何耦合和複雜的事情可以得到。 '要解決這個新問題.... – 2010-06-11 09:28:27

0

或者,您可以通過將電子郵件地址移到密鑰名稱並將用戶設置爲父實體來重構您的聯繫人模型。您的收件人屬性將更改爲原始電子郵件地址的字符串列表。這爲您提供了一個靜態的電子郵件收件人列表,而無需爲每個收件人提取一組相應的實體,或者要求這些實體仍然存在。如果您想獲取聯繫人實體,您可以輕鬆地從用戶和收件人地址構建密鑰。

這裏的一個限制是,現有聯繫人實體上的電子郵件地址無法更改,但我認爲您有這個問題。使用現有模型更改聯繫人地址會追溯更改發送郵件的收件人,這是我們所知的一個問題。

相關問題