2010-08-23 59 views
2

我正在組建一個員工數據庫,我需要能夠修改員工信息,但也要跟蹤所有修訂。我應該如何構建數據庫,以便可以對相同的用戶數據進行多次修訂,但是能夠根據最新版本進行查詢?我正在查看很少發生變化的信息,例如Last Name,但我需要能夠查詢過期值。所以如果珍妮史密斯將她的名字改爲詹妮詹姆斯,我需要能夠在我搜索她的舊名時找到用戶當前的信息。我應該在哪裏分手我的用戶記錄以跟蹤修訂

我假設我將至少需要2個表,其中一個包含uid,另一個包含修訂版。然後,我會加入他們,並查詢最新的修訂。但是,我應該進一步分解它,這取決於數據更改的頻率或數據類型?我正在查看每個記錄約40個字段,每個更新只有一個或兩個字段可能會更改。此外,我無法從數據庫中刪除任何數據,我需要能夠回顧以前的所有記錄。

回答

2

這樣做的一個簡單方法是添加一個已刪除的標誌,而不是更新記錄,在現有記錄上設置已刪除標誌並插入新記錄。

如果您願意,您當然也可以將現有記錄寫入存檔表。但如果變化不頻繁,桌子不大,我就不會打擾。

要獲得活動記錄,使用'where deleted = 0'進行查詢,當此字段上存在索引時,速度影響最小。

通常,這會增加一些其他字段,如修訂號,記錄上次更新時間以及更新記錄的時間。修訂號對於獲得以前的版本以及進行樂觀鎖定非常有用。 '誰更新了最後一次以及什麼時候'的問題通常在系統運行後纔會發生,而不是在需求收集期間出現,並且是包含'主'數據的任何表格的有用字段。

+0

「已刪除」列上的索引如何提供幫助?如果查詢引擎使用此索引,是不是必須對所有其他列執行表掃描?將搜索字段編入索引並放棄搜索結果中刪除的行不是更好嗎? – 2010-08-23 21:36:12

+1

不,它會在已刪除的列上使用索引掃描,然後在其他列中進行搜索。您可以有多個索引,並且查詢優化器將使用數據庫收集的統計信息來估計每個索引的相對性能,並將它們按順序排列,以便首先使用期望得到最少結果的索引。嘗試對一些查詢進行EXPLAIN PLAN,看看它是如何工作的。優化器通常非常聰明,以至於只有10%的記錄被實際刪除時,他們才知道使用索引是不值得的。 – 2010-08-23 21:48:33

+0

所以讓我重申一遍。我會有兩張桌子,其中一名工作人員不變,另一名工作人員的細節可變。該員工詳細信息表中將有一個索引字段(已刪除),我將在爲該工作人員插入新記錄時設置該字段。當我想查詢最新版本時,我只限於刪除= 0的地方。我錯過了什麼嗎? – 2010-08-24 20:32:45

2

我會使用單獨的表格,因爲那樣您就可以擁有一個唯一的標識符,指向所有其他子記錄,這也是表格的PK,我認爲它不太可能會導致數據完整性問題。例如,你有瑪麗瓊斯在地址表和電子郵件表和績效評估表等記錄。如果你添加一個變更記錄到主表,你將如何重新鏈接所有現有的信息?使用單獨的歷史記錄表,這不是問題。

在一個表中刪除字段後,您必須具有非自動生成的人員ID和自動生成的記錄編號。

您還有可能忘記使用幾乎每個查詢所需的where deleted = 0 where子句。 (如果確實使用已刪除的標誌字段,請爲自己做個忙,並使用where deleted = 0設置視圖,並要求開發人員在查詢中使用視圖而不是原始表。)

使用已刪除的標誌字段還需要一個觸發器來確保只有一個記錄被標記爲活動。

+0

+1你說過我的感受。 :-) – 2010-08-23 21:47:25

+0

我看起來至少有兩張表,一張包含工作人員的不可變ID和一張帶有可變工作人員信息的表。這樣我永遠不必刪除一條記錄,因爲每條記錄都將不可變的id設置爲外鍵。我想知道是否應該將兩個表以外的記錄拆分成表格,這些表格中的字段按抽象類型分組或者可能更新。 – 2010-08-24 20:43:21

0

@Peter Tillemans的建議是完成您要求的常用方法。但我不喜歡它。

數據庫的結構應反映正在建模的現實世界事實。

我會爲obsolete_employee創建一個單獨的表格,只存儲將來需要搜索的歷史信息。通過這種方式,您可以保持您的真實員工數據表清潔,並只保留必要的舊數據。這種方法還將簡化與搜索歷史數據無關的應用程序的報告和其他功能。

只要想一想,當你輸入select * from employee而沒有其他任何東西時,你會得到那種溫暖的感覺,正確的善良會迴流!

相關問題