什麼是系統版本的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
)以後才能刪除表