2009-09-25 172 views
3

關於如何審計表的話題最近出現在我們的討論中...所以我喜歡你的意見,最好的辦法是什麼來解決這個問題。在我們的數據庫中,我們有兩種方法的組合(這不是很好),因爲之前的每個DBA都做了他/她認爲正確的方法。所以我們需要改變他們遵循任何一個模型。審計觸發器:使用INSERTED或DELETED系統表

CREATE TABLE dbo.Sample(
Name VARCHAR(20), 
... 
... 
Created_By VARCHAR(20), 
Created_On DATETIME, 
Modified_By VARCHAR(20), 
Modified_On DATETIME 
) 

CREATE TABLE dbo.Audit_Sample(
Name VARCHAR(20), 
... 
... 
Created_By VARCHAR(20), 
Created_On DATETIME, 
Modified_By VARCHAR(20), 
Modified_On DATETIME 
Audit_Type VARCHAR(1) NOT NULL 
Audited_Created_On DATETIME 
Audit_Created_By VARCHAR(50) 
) 

方法1:商店,在審計表從主表中刪除對於被替換,只有那些記錄/(使用系統表刪除)。因此,對於主表中的每個UPDATE和DELETE,正在被替換的記錄被插入審計表中,其中'Audit_Type'列爲萎凋'U'(用於UPDATE)或'D'(用於DELETE)

INSERT未經審覈。對於任何記錄的當前版本,您總是查詢主表。對於歷史記錄,您可以查詢審計表。

優點:似乎很直觀,用於存儲以前版本的記錄 缺點:如果您需要了解特定記錄的歷史記錄,則需要將審計表與主表連接起來。

Appraoch 2:在審計表中存儲每個進入主表的記錄(使用系統表INSERTED)。

INSERTED/UPDATED/DELETED到主表的每條記錄也存儲在審計表中。所以當你插入一條新記錄時,它也被插入到審計表中。更新後,新版本(來自INSERTED)表存儲在審計表中。被刪除時,舊版本(來自DELETED)表被存儲在審計表中。優點:如果您需要了解特定記錄的歷史記錄,則可以在一個位置查看所有記錄。

雖然我沒有在這裏列出所有這些,每種方法都有其優點和缺點嗎?

回答

4

我會去用:

Appraoch 2:存儲,在審計表中,每一個進入主表 (利用插入系統表)記錄。

是每行一行真的會殺死數據庫嗎?這樣你就可以完整地記錄下歷史。

如果您清除出列(一個範圍內的所有比X天以上),你仍然可以告訴我們,如果事情已經改變與否:

  • 如果審計行存在(尚未清除),你可以看到,如果行問題改變了。
  • 如果該項目不存在審計行(全部被清除)什麼都沒有改變(因爲任何改變寫入審計表,其中包括全新的項目)

如果用Appraoch 1走:和清除了範圍內,它將很難(需要記住清除日期)告訴新的插入與清除所有行的插入。

+0

在我把所有的想法寫進這個問題後,重新閱讀之後,我也有同樣的想法。方法2似乎是一個更好的方法。小小的頭頂可以忽略不計。感謝您的輸入。 – 2009-09-25 18:20:26

0

我們使用很多第三種方法是隻審覈感興趣的列,並在每一行保存'新'和'舊'值。

因此,如果您有「名稱」列,審計表將具有「name_old」和「name_new」。

在INSERT觸發器中,根據您的偏好將「name_old」設置爲空/ null,並且「name_new」設置爲INSERTED。 在UPDATE觸發器中,「name_old」設置爲DELETED,而來自INSERTED的「name_new」設置爲 在DELETE觸發器中,將「name_old」設置爲DELETED,將「new_name」設置爲blank/null。

(或您使用FULL加入和所有情形之一的觸發)

對於VARCHAR領域,這可能看起來不像一個好主意,但對於INTEGER,DATETIME等提供,它是非常受益容易看到更新的區別。

I.e.如果你在你的真正的表有一個量場,並從5更新到7,你必須在審計表:

quantity_old quantity_new 
      5    7 

輕鬆就可以計算出的數量是在特定的時間增加了2個。

如果您在審計表中有單獨的行,您將不得不加入一行以「下一個」計算差異 - 在某些情況下這可能會非常棘手......

+0

感謝您的回覆。我以前聽說過這種方法,但從未實現過。我會進一步思考。 謝謝, _UB – 2009-09-25 17:34:48