账本注意事项和限制

适用于:SQL Server 2022 (16.x) Azure SQL 数据库 Azure SQL 托管实例

由于系统版本控制和不可变数据的特性,在使用账本表时,有一些应考虑的注意事项和限制。

一般注意事项和限制

使用账本时,请考虑以下事项。

  • 账本数据库(账本属性设置为启用的数据库)无法转换为账本属性设置为关闭的常规数据库。
  • 数据库摘要的自动生成和存储目前在 Azure SQL 数据库中可用,但在 SQL Server 上不受支持。
  • 在账本表中使用 Azure 存储不可变 blob 进行的自动摘要管理不支持用户使用本地冗余存储 (LRS) 帐户。
  • 创建账本数据库时,默认情况下在数据库中创建的所有新表(未指定 APPEND_ONLY = ON 子句)将是可更新账本表。 要创建仅追加账本表,请使用 CREATE TABLE (Transact-SQL) 语句中的 APPEND_ONLY = ON 子句。
  • 一个事务最多可更新 200 个账本表。

账本表的注意事项和限制

  • 数据库中不属于账本表的现有表无法转换为账本表。 有关详细信息,请参阅将数据从常规表迁移到账本表
  • 创建账本表后,不能将其还原为不是账本表的表。
  • 不支持删除仅追加账本表可更新账本表的历史记录表中的旧数据。
  • TRUNCATE TABLE 不受支持。
  • 创建可更新的账本表时,会向账本表添加四个 GENERATED ALWAYS 列。 仅追加账本表会向账本表添加两列。 这些新列将计入 Azure SQL 数据库中支持的最大列数 (1,024)。
  • 不支持内存中的表。
  • 不支持稀疏列集。
  • 不支持 SWITCH IN/OUT 分区。
  • 不支持 DBCC CLONEDATABASE。
  • 账本表不能具有全文检索功能。
  • 账本表不能是图形表。
  • 账本表不能是 FileTable。
  • 账本表具有聚集列存储索引时,不能具有行存储非聚集索引。
  • 不允许在历史记录表上跟踪更改,但账本表中允许跟踪更改。
  • 不允许在历史记录表上进行变更数据捕获,但在账本表中允许。
  • 账本表不支持事务复制。
  • 不支持数据库镜像。
  • 只有账本表支持 Azure Synapse Link,历史记录表不支持。
  • 将数据库备份本机还原到 Azure SQL 托管实例后,手动更改摘要路径。
  • 在 Azure SQL 托管实例上创建托管实例链接后手动更改摘要路径。
  • 账本表不支持SQL 数据同步。

不支持的数据类型

  • XML
  • SqlVariant
  • 用户定义数据类型
  • FILESTREAM

时态表的限制

可更新账本表基于时态表的技术,并继承大部分而非全部限制。 下面是继承自时态表的限制列表。

  • 如果历史记录表的名称是在历史记录表创建期间指定的,则必须指定架构和表的名称,以及账本视图的名称。
  • 默认情况下,历史记录表是经过 PAGE 压缩的。
  • 如果当前表已分区,则历史记录表在默认文件组上创建,因为不会自动将分区配置从当前表复制到历史记录表。
  • 时态表和历史记录表不能为 FILETABLE,且可以包含 FILESTREAM 以外的任何受支持的数据类型的列。 FILETABLE 和 FILESTREAM 允许在 SQL Server 外部进行数据操作,因此系统版本控制不能得到保证。
  • 不能将节点或边缘表创建为时态表或将其更改为时态表。 账本不支持 Graph。
  • 尽管时态表支持 Blob 数据类型,如 (n)varchar(max)varbinary(max)(n)textimage,但由于其大小,会导致产生巨大的存储成本,并可能对性能产生影响。 因此在设计系统的过程中,应慎重使用这些数据类型。
  • 必须在当前表所在的数据库中创建历史记录表。 不支持对链接服务器的时态查询。
  • 历史记录表不能有约束(主键、外键、表或列约束)。
  • 对于经系统版本控制的时态表,联机选项 (WITH (ONLINE = ON) 对 ALTER TABLE ALTER COLUMN 不起任何作用。 无论为 ONLINE 选项指定的值是什么,都不会联机执行 ALTER COLUMN
  • INSERTUPDATE 语句不能引用 GENERATED ALWAYS 列。 将阻止将值直接插入这些列的尝试。
  • UPDATETEXTWRITETEXT 不受支持。
  • 历史记录表上不能有触发器。
  • 复制技术的使用受到限制:
    • 始终启用: 完全支持
    • 快照、合并和事务复制:时态表不支持
  • 在历史记录表链中,无法将历史记录表配置为当前表。
  • 创建历史记录表后,不会将下列对象或属性从当前表复制到历史记录表:
    • 时间段定义
    • 标识定义
    • 索引
    • 统计信息
    • 检查约束
    • 触发器
    • 分区配置
    • 权限
    • 行级别安全性谓词

架构更改的注意事项

添加列

支持添加可为空的列。 不支持添加不可为 null 的列。 账本专用于在计算行版本的哈希时忽略 NULL 值。 基于此,添加可为空的列时,账本将修改账本架构和历史记录表以包含新列,但这不会影响现有行的哈希。 在账本表中添加列的操作是在 sys.ledger_column_history 中捕获的。

删除列和表

通常,删除列或表时,会完全擦除数据库中的基础数据,从根本上讲,这与需要数据不可变的账本功能不兼容。 账本不会删除数据,而是重命名要删除的对象,以便这些对象从用户架构中逻辑删除,但在物理上仍保留在数据库中。 任何已删除的列也隐藏在账本表架构中,以便对用户应用程序不可见。 但是,此类已删除对象的数据仍可用于账本验证过程,并让用户可以通过相应的账本视图检查历史数据。 在账本表中删除列的操作是在 sys.ledger_column_history 中捕获的。 删除账本表的操作是在 sys.ledger_table_history 中捕获的。 删除账本表及其依赖对象后,它们在系统目录视图中将被标记为“已删除”并重命名:

  • 通过在 sys.tables 中设置 is_dropped_ledger_table 将已删除的账本表标记为“已删除”并使用以下格式重命名:MSSQL_DroppedLedgerTable_<dropped_ledger_table_name>_<GUID>
  • 使用以下格式重命名可更新账本表的已删除历史记录表:MSSQL_DroppedLedgerHistory_<dropped_history_table_name>_<GUID>
  • 通过在 sys.views 中设置 is_dropped_ledger_view 将已删除的账本视图标记为“已删除”并使用以下格式重命名:MSSQL_DroppedLedgerView_<dropped_ledger_view_name>_<GUID>

注意

如果重命名的表或视图的长度超过 128 个字符,则删除的账本表、历史记录表和账本视图的名称可能被截断。

更改列

不影响账本表基础数据的更改都受支持且无需任何特殊处理,因为它们不影响在账本中捕获的哈希。 这些更改包括:

  • 更改为 Null 性
  • Unicode 字符串的排序规则
  • 变量长度列的长度

但是,可能影响现有数据格式的操作都不受支持,例如更改数据类型。