在数据库管理中,误操作如误删、误更新几乎是每个 DBA 都会遇到的问题。传统依赖备份的恢复方式不仅耗时,而且往往需要停机,影响业务连续性。自SQL Server 2016起,系统版本控制临时表(System-Versioned Temporal Tables)为解决这些问题提供了一条革命性的路径,让数据“穿越时间”成为可能。1. 临时表的双表架构
组件 | 功能 | 存储内容 |
|---|
当前表(Current Table) | 提供实时业务访问 | 数据的最新状态及 ValidFrom 时间戳 |
历史表(History Table) | 自动审计与追溯 | 数据的所有历史修订版本及有效期 |
每当当前表中的行被更新或删除时,SQL Server 引擎会自动将旧版本数据及其有效期戳移入历史表。这一机制完全透明,应用层无需额外逻辑即可获得历史数据。💡 换句话说,你的数据库就像开了“时间机器”,可以回到某一时刻查看或恢复数据。
接下来的操作步骤+命令示例教你如何启用临时表、查询历史数据,并恢复误操作的数据。1. 创建系统版本控制临时表
CREATE TABLE dbo.Employees ( ID INT PRIMARY KEY, Name NVARCHAR(50), Salary DECIMAL(10,2), ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START, ValidTo DATETIME2 GENERATED ALWAYS AS ROW END, PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo))WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.EmployeesHistory));
✅ 完成后,表的更新和删除都会自动记录历史版本,无需手动操作。2. 插入初始数据
INSERT INTO dbo.Employees (ID, Name, Salary) VALUES(101, '张三', 8000),(102, '李四', 9000),(103, '王五', 10000);
3. 模拟误操作
DELETE FROM dbo.Employees WHERE ID = 101;
UPDATE dbo.EmployeesSET Salary = Salary * 0.8WHERE ID = 102;
4. 查询历史数据
使用 FOR SYSTEM_TIME 子句,可以查看历史版本数据:SELECT *FROM dbo.EmployeesFOR SYSTEM_TIME AS OF '2026-04-02 09:53:45';
SELECT *FROM dbo.EmployeesFOR SYSTEM_TIME BETWEEN '2026-04-02 09:53:06' AND '2026-04-02 09:54:06';
5. 恢复误删除或误更新的数据
恢复误删除的单行数据
INSERT INTO dbo.Employees (ID, Name, Salary)SELECT ID, Name, SalaryFROM dbo.EmployeesFOR SYSTEM_TIME AS OF '2026-04-02 09:53:45'WHERE ID = 101;
UPDATE eSET e.Salary = h.SalaryFROM dbo.Employees AS eJOIN dbo.Employees FOR SYSTEM_TIME AS OF '2026-04-02 09:54:06' AS hON e.ID = h.IDWHERE e.ID = 102;
注意:FOR SYSTEM_TIME AS OF 是查询历史表的关键,它保证你从历史版本取到的是准确时间点的数据。
总结
与传统备份恢复相比,它对业务几乎零中断,操作灵活、精确,是现代 SQL Server 数据治理的重要工具。
阅读原文:https://mp.weixin.qq.com/s/dwlK1yV3VLM-t6YQSxnq9A
该文章在 2026/4/8 9:20:10 编辑过