10 月 23 - 25 日,QCon 上海站即将召开,现在购票,享9折优惠 了解详情
写点什么

SQL Server 2016:时态表

  • 2015-06-17
  • 本文字数:1478 字

    阅读完需:约 5 分钟

术语“时态数据(temporal data)”是指那些在数据库中有版本的记录。任何给定的逻辑记录都有一个当前版本和零个或多个先前版本。当前版本和任意先前版本在数据库中都以物理行的形式存在,虽然未必在同一张表中。

使用时态表时要努力保证数据完整性。每次更新一个行,都需要有一种方法可以确保行的当前版本复制到存储先前版本的表中。这可以通过触发器或存储过程实现,但两种方法都有各自的问题。

同样,查询时态数据也是个挑战。虽然开发人员很容易获取一条逻辑记录的当前版本,但查询特定数据的版本,需要一个复杂而又容易出错的查询。这经常导致开发人员寄希望于专门为这种负载类型而设计的数据库。

SQL Server 2016 提供了另外一种选择——新的时态表对象。表面上看,时态表看起来跟普通表一样。它支持大多数列类型、普通索引、列存储索引、外键等等。CRUD 类的操作同使用普通 SQL 或对象关系映射一样。实际上,大多数普通表都可以转换成时态表,而不需要修改使用上述表的存储过程和应用程序。

从实现上来说,时态表实际上是两张表。一张表包含当前值,另一张表管理数据的历史版本。两张表链接在一起,普通表的任何 UPDATE 或 DELETE 操作都会自动创建一个相应的历史行。(INSERT 操作不会创建历史记录。)

访问历史数据

开发人员可以直接查询历史表,但由于它不包含当前值,所以不会经常用到它。相反,应该总是使用下面的其中一种操作查询基表:

  • 时间点:AS OF <date_time>
  • 开区间:FROM <start_date_time> TO <end_date_time>
  • 左闭右开:BETWEEN <start_date_time> AND <end_date_time>
  • 闭区间:CONTAINED IN (<start_date_time> , <end_date_time>)

比如,如果想知道 ID 为 27 的客户在第一年中哪个值是活跃的,可以使用查询:

复制代码
FROM Customer FOR SYSTEM_TIME AS OF '2015-1-1' WHERE CustomerID = 27

如果换个需求,想查看客户记录在那天的每个版本,可以使用查询:

复制代码
FROM Customer FOR SYSTEM_TIME BETWEEN '2015-1-1' AND '2015-1-2'WHERE CustomerID = 27

设计原则

  • 时态表需要有一个 SysStartTime 列和一个 SysEndTime 列,两个列均为非空 DateTime2 类型。这些列可以随意命名,由 SQL Server 管理;用户不能插入或更新这些列的值。
  • 不支持 FILESTREAM 列类型,因为它在数据库之外存储数据。
  • 对于表 Foo,历史表的默认表名为“FooHistory”。该名可以覆写。
  • 历史表不能直接修改,只能通过更新或删除当前表的数据增加它的记录。
  • 不支持 INSTEAD OF 触发器,AFTER 触发器只能用在当前表上。

索引必须手动启用。关于这一点,微软给出了一些建议:

为了获得最优的存储大小和性能,一个最优的索引策略是,在当前表上创建一个聚簇列存储索引和 / 或一个 B 树行存储索引,在历史表上创建一个聚簇列存储索引。如果创建 / 使用自己的历史表,那么我们强烈建议创建一个包含当前表主键和时间列的索引,以便提升时态数据查询的速度,以及数据一致性检查操作中一部分查询的速度。如果历史表是行存储的,那么我们建议创建一个聚簇行存储索引。在默认情况下,历史表上会创建一个聚簇行存储索引。至少,我们建议创建一个非聚簇行存储索引。

模式修改

用户不能修改时态表的模式。不过,可以在 ALTER TABLE 语句中使用 SET (SYSTEM_VERSIONING = OFF) 将时态表转换成普通表。

这样做完之后,就可以修改这两张表,然后使用 SET (SYSTEM_VERSIONING = ON) 将它们重新转换成时态表。注意,该语句需要包含历史表的表名和两个系统时间列。

更正:本文的上一个版本曾错误地将 FOR SYSTEM_TIME 表达式描述为 WHERE 子句的一部分,而实际上,它是 FROM 子句的一部分。

查看英文原文: SQL Server 2016: Temporal Tables

2015-06-17 08:322624
用户头像

发布了 1008 篇内容, 共 433.1 次阅读, 收获喜欢 346 次。

关注

评论

发布
暂无评论
发现更多内容

开源demo| ARCall 小程序开源示例发布

anyRTC开发者

小程序 音视频 视频通话 开源demo ARCall

兼容认证|青云QKCP与观测云完成产品兼容性互认证,携手打造云原生可观测能力

观测云

云生态大会,随“峰”而来!

天翼云开发者社区

超实用转型攻略!《2022央国企云原生落地实用指南》重磅发布(附下载链接)

York

云原生 系统架构 数字化转型 信创 国资委中央企业

智慧灯杆展会|2022南京国际智慧灯杆及智慧路灯展览会

AIOTE智博会

百度工程师眼中的云原生可观测性追踪技术

百度Geek说

Java 云原生

瓜分30万奖金!DeepRec CTR模型性能优化天池挑战赛来啦

阿里云大数据AI技术

深度学习

IReport导出PDF字体加粗失效

源字节1号

软件开发 前端开发 后端开发 小程序开发

nacos注册中心之服务地址动态感知

急需上岸的小谢

7月月更

人工智能展会|2022第十四届南京国际人工智能展览会

AIOTE智博会

人工智能展览会

云原生平台,让边缘应用玩出花!

天翼云开发者社区

CDN 云平台

从0到1 拿下C语言—程序结构及使用示例

一碗黄豆酱

【字体反爬】猫X眼YingShi,我们又来欺负你了,用到了 OCR 识别技术

梦想橡皮擦

Python 爬虫 7月月更

可观测性提升软件工程质量,观测云出席2022 QECon全球软件质量&效能大会

观测云

CentOS 8里的这个功能,天翼云SFS弹性文件校准了

天翼云开发者社区

Centos 7 CentOS 8 弹性文件

AntDB数据库产品入选中国信通院《全球数据库产业图谱(2022)》

亚信AntDB数据库

国产数据库

数据治理笔记

老猎人

设计微服务安全架构

Damon

7月月更

IT运维管理指什么?如何建立有效的IT运维管理系统?

行云管家

运维 IT运维 服务器运维

2022第十四届南京国际智慧工地展览会|智慧工地展

AIOTE智博会

智慧工地展览会

绿色低碳天翼云,数字经济新引擎!

天翼云开发者社区

云计算 大数据 AI 数字化转型

精品方案|海泰云密码应用服务解决方案 打造安全合规的云上应用

电子信息发烧客

重磅预告!易观分析联合微软、中央财经大学,共话数字经济

易观分析

数据驱动

阿里云发布《升舱-数据仓库升级交付标准化》白皮书

Lily

iOS中内存管理(ARC)

NewBoy

ios 前端 移动端 iOS 知识体系 7月月更

C#/VB.NET在 Word 中插入水印

Geek_249eec

C# word 添加水印 VB.NET

大咖说·图书分享 | HaaS 物联网设备云端一体开发框架

大咖说

阿里巴巴 物联网 大咖 HaaS

最右×微帧,高质量的HEIF图片编码压缩技术

微帧Visionular

计算机视觉 HEIF 视频编解码 图片压缩 WebP

【等保常见问题解答】等保测评机构能帮忙做等保整改吗?

行云管家

网络安全 等保 等保测评 等保整改

2022第十四届南京国际智慧城市|物联网|大数据博览会

AIOTE智博会

南京智博会 物联网展览会 智慧城市展览会

2022第十五届南京国际工业自动化及工业机器人展览会

AIOTE智博会

SQL Server 2016:时态表_架构_Jonathan Allen_InfoQ精选文章