基本上,您正在尋找跟蹤/審計對錶的更改,同時保持主表的大小不變。
有幾種方法可以解決這個問題。下面討論每種方式的缺點和優點。
1 - 使用觸發器審計表。
如果您正在審計表(插入,更新,刪除),請看我如何避免不需要的事務--SQL星期六幻燈片包含代碼 - http://craftydba.com/?page_id=880。填充審計表的觸發器可以保存來自多個表的信息(如果您選擇),因爲數據保存爲XML。因此,如果需要,可以通過解析XML來取消刪除操作。它追蹤誰和做了什麼改變。
(可選)您可以在其自己的文件組上擁有審覈表。
Description:
Table Triggers For (Insert, Update, Delete)
Active table has current records.
Audit (history) table for non-active records.
Pros:
Active table has smaller # of records.
Index in active table is small.
Change is quickly reported in audit table.
Tells you what change was made (ins, del, upd)
Cons:
Have to join two tables to do historical reporting.
Does not track schema changes.
2 - 有效的約會記錄
如果你是永遠不會從審覈表中清除數據,爲什麼不標記行作爲刪除,但保持它永遠?許多像人一樣的系統使用有效的約會來顯示記錄是否不再有效。在BI世界中,這被稱爲類型2維表(緩慢變化的維度)。請參閱數據倉庫學院文章。 http://www.bidw.org/datawarehousing/scd-type-2/每條記錄都有開始日期和結束日期。
所有活動記錄的結束日期都爲null。
Description:
Table Triggers For (Insert, Update, Delete)
Main table has both active and historical records.
Pros:
Historical reporting is easy.
Change is quickly shown in main table.
Cons:
Main table has a large # of records.
Index of main table is large.
Both active & history records in same filegroup.
Does not tell you what change was made (ins, del, upd)
Does not track schema changes.
3 - 更改數據捕獲(企業功能)。
Micorsoft SQL Server 2008引入了更改數據捕獲功能。雖然這跟蹤數據更改(CDC),事實上使用LOG讀取器,但它缺少諸如誰和做什麼改變之類的事情。 MSDN詳細信息 - http://technet.microsoft.com/en-us/library/bb522489(v=sql.105).aspx
此解決方案依賴於正在運行的CDC作業。 SQL代理的任何問題都會導致數據顯示延遲。
請參閱更改數據捕獲表。 http://technet.microsoft.com/en-us/library/bb500353(v=sql.105).aspx
Description:
Enable change data capture
Pros:
Do not need to add triggers or tables to capture data.
Tells you what change was made (ins, del, upd) the _$operation field in
<user_defined_table_CT>
Tracks schema changes.
Cons:
Only available in enterprise version.
Since it reads the log after the fact, time delay in data showing up.
The CDC tables do not track who or what made the change.
Disabling CDC removes the tables (not nice)!
Need to decode and use the _$update_mask to figure out what columns changed.
4 - 變化跟蹤功能(所有版本)。
Micorsoft SQL Server 2008引入了更改跟蹤功能。與CDC不同,它具有所有版本;然而,它帶有一些TSQL函數,你必須調用它來找出發生了什麼。
它旨在通過應用程序與SQL服務器同步一個數據源。 TechNet上有一個完整的同步框架。
http://msdn.microsoft.com/en-us/library/bb933874.aspx http://msdn.microsoft.com/en-us/library/bb933994.aspx http://technet.microsoft.com/en-us/library/bb934145(v=sql.105).aspx
與疾病預防控制中心,您可以指定最後在數據庫中清除之前多久變化。另外,插入和刪除不記錄數據。更新只記錄更改的字段。
由於您正在將SQL服務器源同步到另一個目標,所以此工作正常。 除非您編寫定期作業以找出更改,否則這不利於審覈。
您仍然需要在某處存儲該信息。
Description:
Enable change tracking
Cons:
Not a good auditing solution
前三種解決方案將適用於您的審計。我喜歡第一個解決方案,因爲我在我的環境中廣泛使用它。
真誠
約翰
代碼段從演示(汽車數據庫)
--
-- 7 - Auditing data changes (table for DML trigger)
--
-- Delete existing table
IF OBJECT_ID('[AUDIT].[LOG_TABLE_CHANGES]') IS NOT NULL
DROP TABLE [AUDIT].[LOG_TABLE_CHANGES]
GO
-- Add the table
CREATE TABLE [AUDIT].[LOG_TABLE_CHANGES]
(
[CHG_ID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
[CHG_DATE] [datetime] NOT NULL,
[CHG_TYPE] [varchar](20) NOT NULL,
[CHG_BY] [nvarchar](256) NOT NULL,
[APP_NAME] [nvarchar](128) NOT NULL,
[HOST_NAME] [nvarchar](128) NOT NULL,
[SCHEMA_NAME] [sysname] NOT NULL,
[OBJECT_NAME] [sysname] NOT NULL,
[XML_RECSET] [xml] NULL,
CONSTRAINT [PK_LTC_CHG_ID] PRIMARY KEY CLUSTERED ([CHG_ID] ASC)
) ON [PRIMARY]
GO
-- Add defaults for key information
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_CHG_DATE] DEFAULT (getdate()) FOR [CHG_DATE];
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_CHG_TYPE] DEFAULT ('') FOR [CHG_TYPE];
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_CHG_BY] DEFAULT (coalesce(suser_sname(),'?')) FOR [CHG_BY];
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_APP_NAME] DEFAULT (coalesce(app_name(),'?')) FOR [APP_NAME];
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_HOST_NAME] DEFAULT (coalesce(host_name(),'?')) FOR [HOST_NAME];
GO
--
-- 8 - Make DML trigger to capture changes
--
-- Delete existing trigger
IF OBJECT_ID('[ACTIVE].[TRG_FLUID_DATA]') IS NOT NULL
DROP TRIGGER [ACTIVE].[TRG_FLUID_DATA]
GO
-- Add trigger to log all changes
CREATE TRIGGER [ACTIVE].[TRG_FLUID_DATA] ON [ACTIVE].[CARS_BY_COUNTRY]
FOR INSERT, UPDATE, DELETE AS
BEGIN
-- Detect inserts
IF EXISTS (select * from inserted) AND NOT EXISTS (select * from deleted)
BEGIN
INSERT [AUDIT].[LOG_TABLE_CHANGES] ([CHG_TYPE], [SCHEMA_NAME], [OBJECT_NAME], [XML_RECSET])
SELECT 'INSERT', '[ACTIVE]', '[CARS_BY_COUNTRY]', (SELECT * FROM inserted as Record for xml auto, elements , root('RecordSet'), type)
RETURN;
END
-- Detect deletes
IF EXISTS (select * from deleted) AND NOT EXISTS (select * from inserted)
BEGIN
INSERT [AUDIT].[LOG_TABLE_CHANGES] ([CHG_TYPE], [SCHEMA_NAME], [OBJECT_NAME], [XML_RECSET])
SELECT 'DELETE', '[ACTIVE]', '[CARS_BY_COUNTRY]', (SELECT * FROM deleted as Record for xml auto, elements , root('RecordSet'), type)
RETURN;
END
-- Update inserts
IF EXISTS (select * from inserted) AND EXISTS (select * from deleted)
BEGIN
INSERT [AUDIT].[LOG_TABLE_CHANGES] ([CHG_TYPE], [SCHEMA_NAME], [OBJECT_NAME], [XML_RECSET])
SELECT 'UPDATE', '[ACTIVE]', '[CARS_BY_COUNTRY]', (SELECT * FROM deleted as Record for xml auto, elements , root('RecordSet'), type)
RETURN;
END
END;
GO
--
-- 9 - Test DML trigger by updating, deleting and inserting data
--
-- Execute an update
UPDATE [ACTIVE].[CARS_BY_COUNTRY]
SET COUNTRY_NAME = 'Czech Republic'
WHERE COUNTRY_ID = 8
GO
-- Remove all data
DELETE FROM [ACTIVE].[CARS_BY_COUNTRY];
GO
-- Execute the load
EXECUTE [ACTIVE].[USP_LOAD_CARS_BY_COUNTRY];
GO
-- Show the audit trail
SELECT * FROM [AUDIT].[LOG_TABLE_CHANGES]
GO
-- Disable the trigger
ALTER TABLE [ACTIVE].[CARS_BY_COUNTRY] DISABLE TRIGGER [TRG_FLUID_DATA];
**看審計表的&感覺**
您是否考慮過使用'Table-A'上的觸發器爲您創建'Table-A-History'行?確保它們設置爲最後觸發([sp_settriggerorder](http://msdn.microsoft.com/en-us/library/ms186762.aspx))。 – HABO 2012-08-09 19:59:44
不,我沒有。我會研究觸發器。謝謝。 – Mausimo 2012-08-09 20:01:20