放假之前老大跟我提起了一下2016有個有趣的功能叫 Temporal Table ,今天去看了一下資料整理一下。
這個功能看上去像是臨時表,但是其實是系統維護的一個歷史記錄表。(在某個程度上面比起我們手動維護的歷史表應該方便了一點的)
簡單直接的說,它的界面看起來是這樣的(就像是T1一樣) 創建了之后,就會在下面有一個T1History的表中表來記錄。
然后我們來試下怎么去玩這個功能。首先,確認你的Sql Server 版本是2016。然后我們通過一個這樣的語句來創建表
Use Test go create 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 T1 select * from T1History ID COl1 TimeFrom TimeTo ----------- -------------------------------------------------- --------------------------- --------------------------- 1 1111 2016-10-07 07:28:30.3598532 9999-12-31 23:59:59.9999999 2 2222 2016-10-07 07:28:30.3598532 9999-12-31 23:59:59.9999999 3 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 = 2 select * from T1 select * from T1History ID COl1 TimeFrom TimeTo ----------- -------------------------------------------------- --------------------------- --------------------------- 1 1111 2016-10-07 07:28:30.3598532 9999-12-31 23:59:59.9999999 2 2222New 2016-10-07 07:30:38.0561513 9999-12-31 23:59:59.9999999 3 3333 2016-10-07 07:28:30.3598532 9999-12-31 23:59:59.9999999 ID 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 = 3 select * from T1 select * from T1History ID COl1 TimeFrom TimeTo ----------- -------------------------------------------------- --------------------------- --------------------------- 1 1111 2016-10-07 07:28:30.3598532 9999-12-31 23:59:59.9999999 2 2222New 2016-10-07 07:30:38.0561513 9999-12-31 23:59:59.9999999 ID COl1 TimeFrom TimeTo ----------- -------------------------------------------------- --------------------------- --------------------------- 2 2222 2016-10-07 07:28:30.3598532 2016-10-07 07:30:38.0561513 3 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 的提醒,創建這種類型的表需要有主鍵才行~居然忘記了