2011-08-19 20 views
4

這是使用PHP/MySQL的CRM應用程序。用戶可以「刪除」各種實體,如客戶,聯繫人,備註等。我並不是真正從數據庫中刪除該實體,而是希望將其刪除到應用程序中,但保留在數據庫中,並在稍後需要時能夠「恢復」。甚至可能會在應用程序中添加某種「回收站」。爲數據庫實體啓用「取消刪除」的最佳實踐?

我已經考慮了幾種方法可以做到這一點:

  1. 移動刪除實體到另一個表。 (customer to customer_deleted)

  2. 更改實體上的屬性。 (啓用爲false)

我敢肯定還有其他的方式和每個對DB尺寸,性能等自己的影響,我只是想知道什麼是一般推薦的方法做這樣的事情?

+0

'customer_deleted'策略會在數據庫中創建大量的結構冗餘。這將是無益的。 – bzlm

回答

1

我會去兩者的結合:

  1. 設置一個標誌deleted
  2. 使用一個cronjob一段時間後移動條目類型ARCHIVE
  3. 的tabelle如果您需要恢復條目,select into文章列表並從存檔中刪除

爲什麼我會這樣呢?

  • 如果客戶刪除了錯誤的,則可能在恢復被instand
  • 做了幾個星期/月項目表可能會增長到多少後,所以我會歸檔在1周刪除所有條目PA
+0

我不同意將'article'數據移動到另一個表中,純粹是因爲可能存在外鍵約束和級聯操作。 – adlawson

+0

@adlawson我不明白哪裏有層疊操作需要。如果客戶希望「取消刪除」某篇文章,他必須查看存檔。如果您有一個包含1000000個已刪除文章的表格,並且表格中的某處有100個活動文章,則會出現性能和存儲問題。我是商業/媒體數據中心的系統管理員。這是許多CMS系統中最大的問題之一(並且已經由好的CMS公司解決) –

+0

需要採取的措施。如果您正在處理「已刪除」的數據遠遠超過「活躍」數據的數據,那麼將其存儲在單獨的表中可能會有所幫助。我提到的級聯操作適用於文章註釋或其他「子」數據類型,其中DELETE級聯很常見。連接必須改變,級聯操作可能必須從數據庫移到應用程序中,但這取決於您的特定需求。 – adlawson

0

通常的做法是將deleted_at列設置爲實體被用戶刪除的日期(默認爲null)。您還可以包含一個deleted_by列用於標記誰刪除了它。使用某種刪除的列使得FK關係更容易處理,因爲這些不會中斷。通過將該行移動到新表中,您將不得不更新FK(並且如果您未刪除,則再次更新它們)。缺點是你必須確保你所有的查詢都排除了被刪除的行(如果你將行移到了新表中,這不會成爲問題)。許多ORM使得這個過濾更容易,所以這取決於你使用的是什麼。

+0

+1良好的響應。我想補充一點,Doctrine 1.2用它的軟刪除行爲來做到這一點。即使你不使用Doctrine 1.2,你也可以檢查它們的實現並重現相似的模式。 – adlawson

+0

哈!學說軟刪除行爲是我最初挑選的地方!它們使排除deleted_at行變得非常簡單;即使你正在連接到刪除外部行的表上。 Hibernate也具有與Java相似的功能。 – Brad