首页 > 代码库 > Sql Server 2016 新功能——内置的 Temporal Tables
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 我是凑数的╮(╯_╰)╭ ~请其他大神指导补充
5 谢谢@wy123 的提醒,创建这种类型的表需要有主键才行~居然忘记了
Sql Server 2016 新功能——内置的 Temporal Tables