2012-06-26 45 views
1

我有一個「服務」表來詳細說明我們提供的服務。在需要記錄的數據是幾個小一個一對多的關係(所有帶外鍵約束的service_id),如:如何使用一對多關係在表格上保留記錄歷史記錄?

service_owners -- user_ids responsible for delivery of service 
service_tags -- e.g. IT, Records Management, Finance 
customer_categories -- ENUM value 
provider_categories -- ENUM value 
software_used -- self-explanatory 

我的問題是,我想保持更新的歷史到一個服務,爲此我在表上使用了一個更新觸發器,該服務執行一個插入到匹配原始列的歷史表中的插入。但是,如果使用上述數據的規範化方法,並且每個一對多關係具有單獨的表和外鍵,則這些表上的任何更新都不會在服務的歷史記錄中識別。

有沒有人有任何建議?看起來我需要在服務表中存儲子鍵以維護服務歷史的完整性。分隔的文本字段是一種有效的方法,或者,因爲我使用的是PostgreSQL,數組也可能是一個有效的選項?雖然這些感覺有些骯髒!

謝謝。

+0

您的歷史記錄表不必被歸一化。爲了成爲真實的歷史,它必須包含歷史記錄行寫入時的類別值。 –

回答

2

如果你的表是:

create table T (
    ix int identity primary key, 
    val nvarchar(50) 
) 

和你的歷史記錄表是:

create table THistory (
    ix int identity primary key, 
    val nvarchar(50), 
    updateType char(1), -- C=Create, U=Update or D=Delete 
    updateTime datetime, 
    updateUsername sysname 
) 

然後你只需要把更新觸發感興趣的所有表。然後你可以找出歷史上任何一個/所有表的狀態,以確定當時的關係。

+0

嗨。這是我已經考慮過的事情,但是這不會要求使用start_date和end_date列的只插入子表嗎? (子錶的歷史數據將隨着活動數據開始存儲,其中表格會膨脹)。這對於服務表本身中的ENUM數組或列是肯定更可取的嗎?謝謝。 – circular

+0

只有一個活動表和一個歷史表。歷史表不需要任何關係,它們只保存活動表的每一行的歷史副本。活動表不參考任何歷史表。每當活動表更新時,觸發器都會確保歷史記錄表獲取新數據的新行。 – Ben

+0

我認爲表格Thistory中的大多數列應該設置爲NOT NULL。 (當然,取決於你的用例!) – RoachLord

2

我會盡可能避免在任何數據庫中使用數組。

我不喜歡更新,因爲你在這裏說的確切原因......你在寫完之後會失去信息。我的回答很簡單,不要更新。不知道你是否可以實現這一點......但如果你能,我建議使用主表本身來存儲歷史(不需要第二組歷史表)。

將一列添加到名爲'active'的主標題表中。這可以是一個字符或一個位(0關閉,1打開)。然後,這是一個觸發魔術......當更新被執行時,你插入一行到表中相同的記錄覆蓋狀態爲'0'(或不活動),然後更新現有的行(這進程保持活動記錄上的ID列相同,新插入的記錄是具有新ID的非活動記錄)。

這樣,沒有數據的丟失(當然你存儲相當多的行...)和歷史可以很容易地與選擇觀看其中活躍= 0

這裏的痛苦,如果你是處理已經實現的內容......每個存在於該表中的現有查詢都需要更新以包含對活動列的檢查。如果你正在設計一個新系統,使得這個解決方案非常容易實現,但是如果它是一個長期的應用程序,那麼這個解決方案會很痛苦不幸的是,現有的報告將包括關閉記錄和記錄(直到您可以修改where子句)

相關問題