2010-03-27 71 views
2

我是J2EE開發人員&我們使用的是PostgreSQL數據庫的hibernate映射。如何保留數據庫中修改的歷史細節(審計跟蹤)?

我們需要跟蹤的數據庫中發生的任何變化,在別人的話任何領域的所有以前&電流值應保存。每個字段可以是任何類型(BYTEA,INT,焦炭......)

用一個簡單的表很容易,但我們的目標事物的圖形都比較困難。

所以我們用UML的觀點來講,一個對象圖要存儲在數據庫中,每個用戶改變&。

任何想法或模式如何做到這一點?

回答

1

執行此操作的常用方法是存儲對象版本。

如果添加一個「版本」和「刪除」字段,你要存儲的審計線索的每個表,然後而不是做正常的更新和刪除,請遵循以下規則:

  • 插入 - 將版本號設置爲0並正常插入。
  • 更新 - 增加版本號並改爲插入。
  • 刪除 - 增加版本號,將刪除的字段設置爲true,然後執行插入操作。
  • 檢索 - 獲取最高版本號的記錄並返回該記錄。

如果遵循此模式,每次更新時都會創建新記錄而不是覆蓋舊數據,因此您將始終能夠追溯並查看所有舊對象。

這將工作完全相同的對象的關係圖中相同,只是添加新的字段以每個表中的對象圖內,並且處理每個插入/更新/如上所述刪除每個表。

如果您需要知道哪些用戶進行的修改,你只需要添加一個「ModifiedBy」領域也是如此。

(你可以做到這一點處理您的DA層的代碼,或者如果你喜歡,你可以使用數據庫觸發器吸引您的更新/刪除/檢索調用和重新處理他們遵守規則。)

顯然,您需要考慮空間要求,因爲每次更新都會產生全新的記錄。如果您的應用程序更新繁重,那麼您將生成大量數據。通常還包含「上次修改時間」字段,以便您可以脫機處理數據庫並刪除比所需時間更早的數據。

+1

請記住,這種方法實際上破壞了關係完整性。在常規表中,我們將有一個主鍵PK_COL。現在我們有一個(PK_COL,VERSION_NO)的UID。這使得強制執行PK_COL在現實世界中唯一標識某些內容的規則變得更加困難。它還使外鍵關係複雜化:如果父記錄發生變化(插入新版本),我們是否插入所有子版本的新版本*即使它們中沒有一個已經更改*?最後,這種方法通過要求額外的過濾器來獲取當前視圖來懲罰最常見的訪問路徑。 – APC 2010-03-28 03:47:10

+0

我之前的評論涉及到這是審計的一般方法。可能存儲「對象圖」的數據庫幾乎不需要關係完整性,在這種情況下,該技術可以滿足Mada的要求。 – APC 2010-03-28 03:52:34

1

當前的RDBMS實現並不擅長處理時態數據。這就是爲什麼通過觸發器維護單獨的日記表的一個原因是通常的方法。 (另一個原因是審計跟蹤對於常規數據經常具有不同的用例,並且將它們放在單獨的表中可以更容易地管理對它們的訪問)。 Oracle在其Total Recall product中做了一個非常漂亮的工作來隱藏管道,但作爲Oracle,它爲此收取$$$。

斯科特·貝利發表了對PostgreSQL中時間數據的介紹。唉,它現在不會幫你,但它似乎有些功能計劃爲8.5和8。6將啓用時間相關數據的透明存儲。 Find out more