你的位置:首页 > 数据库

[数据库]Sql Server 2016 新功能——内置的 Temporal Tables

放假之前老大跟我提起了一下2016有个有趣的功能叫 Temporal Table ,今天去看了一下资料整理一下。

这个功能看上去像是临时表,但是其实是系统维护的一个历史记录表。(在某个程度上面比起我们手动维护的历史表应该方便了一点的)

简单直接的说,它的界面看起来是这样的(就像是T1一样) 创建了之后,就会在下面有一个T1History的表中表来记录。

 然后我们来试下怎么去玩这个功能。首先,确认你的Sql Server 版本是2016。然后我们通过一个这样的语句来创建表

Use Testgocreate table T1(ID int identity primary key,  COl1 nvarchar(50),  TimeFrom datetime2 generated always as row start,  TimeTo datetime2 generated always as row end,  period for system_time(TimeFrom,TimeTo)) with (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.T1History));

 

这里我就简单的创建一个只有自增主键和一个列的表。创建System_Versioning 的表。必须有2个声明为datetime2 的时间字段才行,因为需要用这2个字段来记录数据的产生轨迹。

比如这里我是使用一个TimeFrom 的字段表示数据的作用开始时间,而TimeTo表示这行数据的失效时间(比方说数据被修改,被删除,那么TimeTo就会记录着修改,删除的时间)

下面我们进行测试,先做测试样例,然后再说明

Step 1:新增数据

insert into T1 (Col1)   values ('1111'),('2222'),('3333')select * from T1select * from T1HistoryID     COl1                        TimeFrom          TimeTo----------- -------------------------------------------------- --------------------------- ---------------------------1      1111                        2016-10-07 07:28:30.3598532 9999-12-31 23:59:59.99999992      2222                        2016-10-07 07:28:30.3598532 9999-12-31 23:59:59.99999993      3333                        2016-10-07 07:28:30.3598532 9999-12-31 23:59:59.9999999(3 行受影响)ID     COl1                        TimeFrom          TimeTo----------- -------------------------------------------------- --------------------------- ---------------------------

 

新增的时候,数据都是最新的版本,所以在历史表里面并不存在记录(注明一点,TimeFrom 和TimeTo 这2个字段将由系统控制维护,并不需要手工插入,如果显示写入这个字段,将抛出错误。系统维护这2个字段,采用的时间将使用UTC格式的时间,对于我们国内,就是小时-8的操作)

 

Step 2:修改数据

update T1 set Col1 = Col1+'New' where ID = 2select * from T1select * from T1HistoryID     COl1                        TimeFrom          TimeTo----------- -------------------------------------------------- --------------------------- ---------------------------1      1111                        2016-10-07 07:28:30.3598532 9999-12-31 23:59:59.99999992      2222New                      2016-10-07 07:30:38.0561513 9999-12-31 23:59:59.99999993      3333                        2016-10-07 07:28:30.3598532 9999-12-31 23:59:59.9999999ID     COl1                        TimeFrom          TimeTo----------- -------------------------------------------------- --------------------------- ---------------------------2      2222                        2016-10-07 07:28:30.3598532 2016-10-07 07:30:38.0561513

 

修改数据的时候。将在历史表里面写入一条历史记录,并将TimeTo设置为当前修改的UTC时间,在主表将保留数据的最新版本。

 

Step 3:删除

delete from T1 where ID = 3select * from T1select * from T1HistoryID     COl1                        TimeFrom          TimeTo----------- -------------------------------------------------- --------------------------- ---------------------------1      1111                        2016-10-07 07:28:30.3598532 9999-12-31 23:59:59.99999992      2222New                      2016-10-07 07:30:38.0561513 9999-12-31 23:59:59.9999999ID     COl1                        TimeFrom          TimeTo----------- -------------------------------------------------- --------------------------- ---------------------------2      2222                        2016-10-07 07:28:30.3598532 2016-10-07 07:30:38.05615133      3333                        2016-10-07 07:28:30.3598532 2016-10-07 07:32:04.3640717

 

删除数据的时候和修改的机制差不多,就是主表删除了行记录,但是历史表保留了一份删除的动作。

 

简单的测试就可以做到这里。下面还有几个测试说明

1 如果使用Merge,那么Merge做的操作将对应以上的增/删/改来维护版本

2 使用了经版本维护的表之后,不能使用truncate table 的操作,因为操作不支持

3 drop 表的时候,不能直接使用drop table 语句,需要先用 ALTER TABLE [dbo].[T1] SET ( SYSTEM_VERSIONING = OFF ) 来把系统维护的版本去掉,然后再分别drop 掉当前表和历史表

4 我是凑数的╮(╯_╰)╭ ~请其他大神指导补充