SQL Server笔记 -- 第69章:时态表

69.1 创建时态表

sql 复制代码
CREATE TABLE 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
  )
)

系统行为:

  • 插入:将 ValidFrom 设为当前事务开始时间(UTC),ValidTo 设为 9999-12-31,标记为"当前"
  • 更新:把旧行复制到历史表,ValidTo 改为当前事务开始时间;当前表写入新行,ValidFrom 同样为当前事务开始时间,ValidTo 保持 9999-12-31
  • 删除:把旧行复制到历史表,ValidTo 改为当前事务开始时间;当前表删除该行
  • MERGE:按 INSERT/UPDATE/DELETE 动作分别执行上述规则

提示:ValidFrom/ValidTo 的值基于事务开始时间;同一事务内所有行的时间戳相同。

69.2 查询所有历史与当前数据

sql 复制代码
SELECT * FROM Employee
FOR SYSTEM_TIME ALL

69.3 创建内存优化的系统版本化时态表并清理历史表

创建时指定历史表名称并启用内存优化:

sql 复制代码
CREATE SCHEMA History
GO

CREATE TABLE dbo.Department (
  DepartmentNumber    char(10) NOT NULL PRIMARY KEY NONCLUSTERED,
  DepartmentName      varchar(50) NOT NULL,
  ManagerID           int NULL,
  ParentDepartmentNumber char(10) NULL,
  SysStartTime        datetime2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
  SysEndTime          datetime2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
  PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)
) WITH (
  MEMORY_OPTIMIZED = ON,
  DURABILITY = SCHEMA_AND_DATA,
  SYSTEM_VERSIONING = ON (
    HISTORY_TABLE = History.DepartmentHistory
  )
)

清理历史表(本地 SQL Server):

sql 复制代码
-- 暂停系统版本化
ALTER TABLE dbo.Employee
SET (SYSTEM_VERSIONING = OFF)
GO

-- 删除过期历史数据
DELETE FROM dbo.EmployeeHistory
WHERE EndTime <= '2017-01-26 14:00:29'

-- 重新启用系统版本化
ALTER TABLE dbo.Employee
SET (
  SYSTEM_VERSIONING = ON (
    HISTORY_TABLE = dbo.EmployeeHistory,
    DATA_CONSISTENCY_CHECK = ON
  )
)

Azure SQL 数据库内置历史清理:

sql 复制代码
-- 数据库级启用
ALTER DATABASE CURRENT
SET TEMPORAL_HISTORY_RETENTION ON
GO

-- 表级设置保留期
ALTER TABLE dbo.Employee
SET (
  SYSTEM_VERSIONING = ON (
    HISTORY_RETENTION_PERIOD = 90 DAYS
  )
)

本地 SQL Server 2016 不支持上述语法,否则报错。

69.4 BETWEEN 查询

返回在指定时间范围内(含上下界)有效的所有行版本:

sql 复制代码
SELECT * FROM Employee
FOR SYSTEM_TIME BETWEEN '2015-01-01' AND '2015-12-31'

69.5 FROM...TO 查询

返回在指定时间范围内曾经有效的所有行版本,不论其开始或结束是否超出边界:

sql 复制代码
SELECT * FROM Employee
FOR SYSTEM_TIME FROM '2015-01-01' TO '2015-12-31'

69.6 CONTAINED IN 查询

仅返回完全落在指定时间范围内的行版本(边界上的开始或结束也包含):

sql 复制代码
SELECT * FROM Employee
FOR SYSTEM_TIME CONTAINED IN ('2015-04-01', '2015-09-25')

69.7 如何查询时态数据

示例:按时间范围与员工 ID 查询并排序

sql 复制代码
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

69.8 返回指定时间点的实际值(AS OF)

返回在指定过去时间点有效的行快照:

sql 复制代码
SELECT * FROM Employee
FOR SYSTEM_TIME AS OF '2016-08-06'
相关推荐
lll23526917792 小时前
2026行业语音转写工具专业术语转写功能横向分析
笔记·智能手机
王中阳Go4 小时前
两个入口答案不一致先别调模型:6 行入口口径对账表(附脚本)
人工智能·后端·python·大语言模型·1024程序员节
geovindu5 小时前
sql:SQL Pagination and Limiting Results using PorstgreSQL 18.0
大数据·数据仓库·sql·postgresql·数据库开发·数据库架构·1024程序员节
码事漫谈6 小时前
消除AI幻觉,普通人能做的五件事
后端
不脱发的程序猿6 小时前
纳指ETF量化策略
数据库·人工智能·1024程序员节
程序员塔塔喵7 小时前
【MySQL篇|第一篇】索引失效的情况
数据库·mysql·索引失效
北京青蓝智慧马老师7 小时前
比外部黑客更难防的,是那个有权限的自己人(3 个脱敏复盘)
大数据·数据库·人工智能
金銀銅鐵7 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(下)
java·后端·ai编程
笃行3508 小时前
拆一台数据集成产品:KFS 的骨架、肌肉和神经
数据库
4SAPI8 小时前
搭建 AI 数据分析工具大模型 API 选型指南
数据库·人工智能·架构·php·1024程序员节