基本上,您正在寻找跟踪/审计对表的更改,同时保持主表的大小不变。
有几种方法可以解决这个问题。下面讨论每种方式的缺点和优点。
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