什么是系统版本的Temporal Table
系统版本的Temporal Table是能够保存历史修改数据而且能够简单的指定时间分析的用户表。 这个Temporal Table就是系统版本的Temporal Table由于每行的有效期由系统托管的。
每一个Temporal Table有2个显示定义的列,类型是datetime2。这些用来表示有效期。这个列用来标记这个行是否是在期间内可用。
除了上面的period列,l临时表也包含了引用到其余表,系统使用这个表来保存行修改删除前的行版本。这个附加表能够认为是history表,主表包含了当前的行版本为当前表。在Temporal Table建立的时候能够指定一个history表或者让系统建立一个默认的history表。
临时表的工做原理
系统版本的表是有一对表,当前表和历史表。这些表都包含2个额外的datetime2字段用来定义每一个行的可用期限:
- 期限开始列:系统把行的开始时间记录在这个列上,称为SysStartTime
- 期限结束列:系统把行的结束时间记录在这个列上,称为SysEndTime
当前表包含了每一个行的当前值。历史表包含每一个行的以前的只,starttime,endtime表示行的可用期限。
如下是一个例子:
CREATE
TABLE
dbo
.
Employee
(
[EmployeeID]
int
NOT
NULL
PRIMARY
KEY
CLUSTERED
,
[Name]
nvarchar
(
100
)
NOT
NULL
,
[Position]
varchar
(
100
)
NOT
NULL
,
[Department]
varchar
(
100
)
NOT
NULL
,
[Address]
nvarchar
(
1024
)
NOT
NULL
,
[AnnualSalary]
decimal
(
10
,
2
)
NOT
NULL
,
[ValidFrom]
datetime2
(
2
)
GENERATED
ALWAYS
AS
ROW
START
,
[ValidTo]
datetime2
(
2
)
GENERATED
ALWAYS
AS
ROW
END
,
PERIOD
FOR
SYSTEM_TIME
(
ValidFrom
,
ValidTo
)
)
WITH
(
SYSTEM_VERSIONING
=
ON
(
HISTORY_TABLE
=
dbo
.
EmployeeHistory
));
能够删除括号中的HISTORY_TABLE系统会自动建立history表。
INSERT:对于一个insert,系统会设置SysStartTime列为当前事务的开始时间,SysEndTime为最大的值9999-12-31
UPDATE:对于update,系统会报以前的行保存到历史表而且设置SysEndTime为当前事务的启动时间。行被关闭,这个期限就是这个行的可用期限。这个行在当前表上的值被修改,那么SysStartTime被设置为当前事务的开始时间。SysEndTime被设置为最大时间。
DELETE:对于删除,系统把以前的行保存到history表,而且设置SysEndtime为事务的开始时间。标记行关闭,期限记录表示行的可用期限。当前表中行被删除。当前的查询不会被查到当前行。只有带时间的查询,或者直接查询历史表才能查到这个行。
MERGE:对于MERGE涉及到3个操做INSERT,UPDATE,DELETE,根据操做的不一样作不一样的记录。
临时数据查询
可使用select from的for system_time子句来查询当前表和历史表的数据。
如下是查询的例子:
SELECT
*
FROM
Employee
FOR
SYSTEM_TIME
BETWEEN
'2014-01-01 00:00:00.0000000'
AND
'2015-01-01 00:00:00.0000000'
WHERE
EmployeeID
=
1000
ORDER
BY
ValidFrom
;
注意:
FOR SYSTEM_TIME会过滤掉SysStartTime=SysEndTime的数据。这些行在同一个事务里面操做了同一行儿产生。只能经过查询历史表才能返回
关于SYSTEM_TIME过滤
表达式 |
符合条件的行 |
Description |
AS OF<date_time> |
SysStartTime <= date_time AND SysEndTime > date_time |
返回一个表,其行中包含过去指定时间点的实际(当前)值。 在内部,临时表及其历史记录表之间将进行联合,而后筛选结果以返回在 <date_time> 参数指定的时间点有效的行中的值。 若是 system_start_time_column_name 值小于或等于 <date_time> 参数值,而且 system_end_time_column_name 值大于 <date_time> 参数值,则此行的值视为有效。 |
FROM<start_date_time>TO<end_date_time> |
SysStartTime < end_date_time AND SysEndTime > start_date_time |
返回一个表,其中包含在指定的时间范围内保持活动状态的全部行版本的值,无论这些版本是在 FROM 自变量的 <start_date_time> 参数以前开始活动,仍是在 TO 自变量的 <end_date_time> 参数值以后中止活动。 在内部,将在临时表及其历史记录表之间进行联合,而后筛选结果,以返回在指定时间范围内任意时间保持活动状态的全部行版本的值。 正好在 FROM 终结点定义的下限时间中止活动的行将被排除,正好在 TO 终结点定义的上限时间开始活动的记录也将被排除。 |
BETWEEN<start_date_time>AND<end_date_time> |
SysStartTime <= end_date_time AND SysEndTime > start_date_time |
与上面的 FOR SYSTEM_TIME FROM <start_date_time>TO<end_date_time> 描述相同,不过,返回的行表包括在 <end_date_time> 终结点定义的上限时间激活的行。 |
CONTAINED IN (<start_date_time> , <end_date_time>) |
SysStartTime >= start_date_time AND SysEndTime <= end_date_time |
返回一个表,其中包含在 CONTAINED IN 参数的两个日期时间值定义的时间范围内打开和关闭的全部行版本的值。 正好在下限时间激活的记录,或者在上限时间中止活动的行将包括在内。 |
ALL |
全部行 |
返回属于当前表和历史记录表的行的联合。 |
注意:
能够经过Hidden隐藏期限列,删除表须要先关闭系统版本
ALTER
TABLE
Employee
SET
(
SYSTEM_VERSIONING
=
off
)以后才能删除表