2013-07-09 17 views
0

這是一個設計問題。日誌表中的外鍵...好還是壞?

比方說,我有一個用戶表{UserKey,UserName},我記錄了一些用戶活動。所以在日誌表{UserKey,Activity}中,我有一個UserKey列。現在是否將日誌表中的UserKey作爲用戶表的Foriegn密鑰?

,據我所看到的,

優點(ForiegnKey):不晃來晃去的記錄。

缺點(ForiegnKey):硬刪除是不可能的,除非我也刪除日誌,這顯然是不好的。

你的建議是什麼?我還缺少什麼?

回答

1

正如你自己所看到的,兩種方法都有優點和缺點。就個人而言,我不希望將外鍵放在日誌表中,因此只有在您添加新記錄時纔會寫入表中,並且日誌表的存儲可以針對追加進行優化。作爲一項好處,您可以使用其原始ID維護關於已刪除項目的日誌記錄。

1

我會建議no-FK (1)雖然我們可以創建一個FK關係,但它並不一定是一個關係。手段,它不是很有意義的說,用戶有很多userevent ...事件有一個單獨的目的。 (2)我們可以允許匿名/訪客用戶,他們也應該記錄事件!

1

缺點(ForiegnKey):hard刪除是不可能的,除非我也刪除日誌,這顯然是不好的。

物理刪除到Users但不是日誌? 我認爲這樣的概念需要重新思考並確定優先順序。

刪除之前我會考慮hideuser

否則,如果您不知道誰做了什麼,那麼保留日誌有什麼意義。

如果不是刪除users而是將它們歸檔,FK並不是真正的FK檢查,而只是一個建議。

+0

日誌應該被清除,而不是刪除。如果用戶在系統中不存在,則日誌應該顯示舊用戶條目..mabye爲簡單字符串。我總是保證去規範化,重複記錄日誌,及時更有意義。歷史是歷史,因爲希特勒不存在了並不意味着二戰沒有發生。 –

0

您的問題有多種解決方案。您可以1. logically delete用戶並保持數據完好無損或您可以在日誌表中2. log the user key only

如果您的用戶數量不多,第一種解決方案非常棒。但它具有性能下降的問題:如果應用程序增長並且用戶數量變大,那麼在Users表中,用戶仍然不活躍,這些記錄會減慢數據庫響應速度(例如,在登錄操作期間) 。

第二種解決方案很好,無論您的應用程序在一段時間內會有多少用戶。但是,您將丟失您刪除的用戶的數據。因此,您將不知道5年前進行了某些活動的已刪除用戶的詳細信息。

還有第三個解決方案:3. using table 'UserArchive' 這個結合了第一個解決方案的優點,並且避免了第二個解決方案的問題。 您可以構建一個名爲UserArchive的新表,其中包含應用程序中存在的所有用戶的數據。將日誌表與UserArchive錶鏈接起來可爲evey用戶提供一些活動的數據,即使該用戶不再存在於Users表中。

當用戶註冊時,您可以在Users表中添加所需的詳細信息,並在UserArchive表中添加一些重要(或全部)詳細信息。 (注意數據冗餘,如果數據庫對您的數據庫有好處或不好,這取決於您) 當用戶想要刪除該帳戶時,您可以自由地將Users表中的硬刪除作爲重要(或全部)細節存儲在UserArchive中。

建議:Users表不應該與UserArchive連接,因爲從邏輯的角度來看,它不是必需的。

這取決於您哪種解決方案最適合您的應用。

3

缺點(ForiegnKey):hard刪除是不可能的,除非我也刪除日誌,這顯然是不好的。

首先,這不是「明顯」壞。這只是處理懸掛記錄的一種方式。順便說一句,您不必從客戶端代碼執行它 - 您可以通過ON DELETE CASCADE引用操作將其自動化,並讓DBMS爲您執行此操作。

另一個是通過具有可NULL的FK(並可能使用ON DELETE SET NULL)。


你根本無法記住這關聯到該數據庫中不再存在的用戶記錄。懸掛記錄可能會保留用戶密鑰,但該密鑰不再具有含義,甚至可以被新用戶重新使用(不太可能,如果您使用自動遞增的ID,但仍有可能)。

但是,您可以「退休」用戶(例如,通過在用戶表中設置標誌)並仍然保留所有記錄,並且可能有一個後臺進程,用於清理已過時不再使用的退休用戶。

在任何情況下,FK是防止懸掛記錄的方式,我會非常不情願放棄它。有了適當的索引,應該沒有性能問題,如果你認爲有問題,請測量,並在做其他事情之前確認它是否存在。