2010-07-08 126 views
4

我們正在SQL 2008 R2上構建大型C#MVC2應用程序(我們也使用Sharp體系結構和Nhibernate作爲生態系統的一部分)的早期階段,其中一個要求是所有數據庫行版本都可以訪問給定的歷史時期。如何實現歷史版本?

我們玩弄類似佈局的思路:

ID(PK)
的recordId
VERSIONID

,並具有一個新的記錄每個編輯,達到創紀錄的結果正與創造相同的recordId和遞增的versionId。然後,記錄顯示將按照SELECT ... WHERE recordId = X AND versionId = MAX(versionId)的順序完成一些操作。

每個事務的快照都不起作用(太多了?並且不能從應用程序中輕鬆訪問)。

但是我們很好奇其他實現方式是否已經嘗試成功,或者存在潛在的問題。

+0

Robert,請在標籤中標明「MSSQL,C#4,NHib,Sharp Arch」等標籤。 – 2010-07-11 05:36:10

回答

3

我們有一個由我們的DBA開發的系統,用作更新/刪除觸發器。有一個輔助表幾乎反映了正在審計的表(除了一些其他的細節,如交易時間,登錄用於更新,服務器等)。任何時候有人進行更改,都會通過觸發器登錄到表格的審覈版本中。每當架構發生變化時,都必須保持審計觸發器的更新,但這種做法很煩人。

關於這個的好處是,應用程序並不需要在所有這個審計關注......所以它使應用程序代碼低(更低)的概念,計數。

這是生產和工作在交易數量在每天數以萬計的表格。您的里程數可能會因您的服務器大小和數據性質等因素而有所不同,但它適用於我們:-)

+0

我第二種方法! – Homer1980ar 2010-07-13 14:32:53

2

而不是versionId,它需要您自行加入得到最大版本,我會介紹validFrom - validTo對。這要求您在插入新版本行時更新(結束)當前記錄的validTo,但可以使用where @now >= validFrom and @now < validTo或任何歷史時間的數據輕鬆選擇當前數據。

您可以將這些歷史記錄存儲在單獨的表中或不存在。如果你想只有一個包含所有行版本的表格,這個表格可以更好的維護和使用,你可能想看看SQL Server分區(分區表),它允許你將最近的歷史和舊的歷史分開,並優化搜索在上面。

1

如果您有SQL 2008 Enterprise,並且根據您的意圖,更改數據捕獲(CDC)值得一看。

這實際上取決於您是否保留以前的版本以進行審計或出於其他原因。

7

你似乎暗指一張臨時表。三種方法:

有效狀態表:追加兩個'時間戳'列(例如,型DATETIME),一種指定當行變爲有效和一個指定當行不再是有效的,中間的時間被該行的有效期間

事務時狀態表:同夥與每一行該行在監視表中存在的時間段,從而允許重建在任何先前時間點的受監視表的狀態。

Bitemporal表:捕獲有效時間和交易時間,同時記錄企業的歷史,同時捕獲歷史記錄的變化順序。

來源:Developing Time-Oriented Database Applications in SQL (Richard T Snodgrass)

2

我有一個類似的問題,我需要審覈的每一個變化,以一組表。嘗試使用只有NHibernate的功能來管理大量的插入和更新(因爲UI需要他們)時

,我們有最大的問題是性能。所以我們的解決方案是使用TRIGGERS來審計表格上的所有信息,並且比較我們當時可能遇到的任何解決方案與NH的響應時間是不可思議的。

如果有人問我該怎麼辦呢,我想說的觸發器是審計數據的方式。

0

我的企業還對審計和歷史使用基於觸發器的方法。除了企業倉庫中的核心表之外,每個重要表還在單獨的數據庫中都有一個審計表。此審計表對於每個事務都有1行。我們的一些表格在第三個數據庫中也有歷史版本。審計數據庫純粹用於事後故障排除和不可否認性 - 但查詢數據分析非常困難且無法執行。我們的歷史數據庫經過優化,能夠非常有效地回答時間點查詢。所有這些都是由我編寫的.net工具編寫的100%腳本,因此,當我們修改模式或向歷史記錄添加新表時,我們只需重新腳本化受影響的觸發器即可。