SQL Server审计功能入门:更改跟踪(Change Tracking)

介绍

       更改跟踪是一种轻量型解决方案,它为应用程序提供了一种有效的更改跟踪机制。常规的,自定义变更跟踪和读取跟踪数据,会使用触发器,存储过程和记录变更的用户表等,

还需要保证访问一致和相关清理工作。 使用CT会减少额外工作量和保证访问一致性。

启用CT的表上必须得有主键,所有版本适用。为了保证更改信息的有效性,官方建议结合快照隔离使用。

CT只能提供:

                    哪些行/列发生了更改

                    被更改行的最新数据。

不能提供:更改发生的次数,中间值。

应用:离线缓存的更新,ETL更新

注意事项

                  1. 写入变更到变更记录表,所以执行计划会多一个操作符,增加开销。

                  2. 每个启用CT的表会创建一个内部更改表。

                  3. 对于用户表中每行的每个更改,都会向内部更改表中添加一行。  该行有一个较小的固定开销,外加一个大小等于主键列大小的可变开销。

                  4. 对于每个已提交的事务,都会向内部事务表中添加一行。

实现

1. 在库级别启用CT
       

alter database TestCT 

set change_tracking=on 

( 

  change_retention=2 days, 

  auto_cleanup=on 

)

2. 对要跟踪的对象启用CT
alter table sometable 

enable change_tracking 

go
3. 使用CHANGETABLE函数查看CT数据。SYS_CHANGE_VERSION是库中任何行的变改的最新版本号。

   返回行的最新更改数据:

SELECT t.* 

      , ct.* 

FROM dbo.SomeTable t 

CROSS APPLY CHANGETABLE(VERSION dbo.SomeTable, (ID), (t. ID)) AS ct;
   返回指定last_sync_versiion改变的数据:
DECLARE @version BIGINT = 2; 

SELECT t.* 

, ct.* 

FROM CHANGETABLE (CHANGES dbo.SomeTable, @version) AS ct 

      INNER JOIN dbo.SomeTable t ON t. ID = ct. ID 

Go

4. 对列启用CT

CREATE TABLE dbo.NewTable ( 

ID INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_NewTable PRIMARY KEY 

      , BigColumn VARCHAR(255) NOT NULL 

      , AnotherBigColumn VARCHAR(255) NOT NULL 

) 

GO 

ALTER TABLE NewTable 

ENABLE CHANGE_TRACKING 

WITH (TRACK_COLUMNS_UPDATED=ON)
5. 查询CT列的变更数据

    使用CHANGE_TRACKING_IS_COLUMN_IN_MASK结合CHANGETABLE

DECLARE @version BIGINT ; 

--get previous version 

SELECT @version= CHANGE_TRACKING_CURRENT_VERSION()-1; 

SELECT *, 

CHANGE_TRACKING_IS_COLUMN_IN_MASK( 

              COLUMNPROPERTY( OBJECT_ID('dbo.NewTable'),'BigColumn','COLUMNID'  

               ), 

         CT.SYS_CHANGE_COLUMNS 

              ) AS BigColumn_Changed, 

CHANGE_TRACKING_IS_COLUMN_IN_MASK( 

                                    COLUMNPROPERTY( 

                        OBJECT_ID('dbo.NewTable'), 

                        'AnotherBigColumn','COLUMNID' 

               ), 

         CT.SYS_CHANGE_COLUMNS 

              ) AS AnotherBigColumn_Changed 

FROM CHANGETABLE(CHANGES dbo.NewTable,@version) AS CT 

INNER JOIN dbo.NewTable NT 

ON CT.ID=NT.ID

总结

    1. 所谓轻量,是相对的。CT仍需要记录变更记录,需要额外的开销。

    2. CT只能记录最终值,所以实际应用中用得不多,只适用于特定场景。

原文地址:https://www.cnblogs.com/Joe-T/p/4312730.html