博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SQL Server 2016新特性:Temporal Table
阅读量:7220 次
发布时间:2019-06-29

本文共 3075 字,大约阅读时间需要 10 分钟。

什么是系统版本的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 
)之后才能删除表
    本文转自 Fanr_Zh 博客园博客,原文链接:http://www.cnblogs.com/Amaranthus/p/7808299.html
,如需转载请自行联系原作者
你可能感兴趣的文章
HDOJ(HDU) 2113 Secret Number(遍历数字位数的每个数字)
查看>>
使用Redis来实现LBS的应用
查看>>
产生唯一随机码的方法分析
查看>>
Java Gradle入门指南之依赖管理(添加依赖、仓库、版本冲突) (转)
查看>>
su 与 su - 比较
查看>>
创业早期,联合创始人如何避免窝里反?(转)
查看>>
多个维度讲解网站打开速度seo优化的措施
查看>>
java.lang.ClassFormatError
查看>>
bash/shell编程学习(2)
查看>>
部门管理制度、规范的建议
查看>>
HTAP数据库 PostgreSQL 场景与性能测试之 12 - (OLTP) 字符串搜索 - 前后模糊查询
查看>>
你还不知道手机精灵?Out啦!
查看>>
嵌入式 VFS: Cannot open root device "mtdblock2" or unknown-block(2,0)
查看>>
规则引擎是什么?最简单的解释
查看>>
水平分库分表的关键步骤和技术难点
查看>>
笔记:Automated Journey Testing with Cascade
查看>>
android JNI的.so库调用
查看>>
在activex控件工程中使用directshow,编译时link错误的解决方法
查看>>
同样的promise,调用方法不一样,执行顺序不一样
查看>>
java-设计模式-责任链
查看>>