可更新账本表

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

可更新账本表是系统版本控制表,用户可对其进行更新和删除,同时还提供防篡改功能。 更新或删除时,行的所有早期版本都将保留在辅助表中,称为历史记录表。 历史记录表反映了可更新账本表的架构。 更新行时,行的最新版本将保留在账本表中,而其早期版本由系统插入到历史记录表中,以透明方式向应用程序显示。

可更新账本表和时态表都是系统版本控制表,其数据库引擎在辅助历史记录表中捕获历史行版本。 任一技术都提供唯一优势。 可更新账本表使当前数据和历史数据都不会被篡改。 时态表支持查询存储在任何时间点的数据,而不是只查询在当前时间点上正确的数据。 可创建既是可更新账本表又是时态表的表来同时使用这两种技术。

Diagram that shows ledger table architecture.

可以通过在 CREATE DATABASE (Transact-SQL) 语句中指定 LEDGER = ON 参数来创建可更新的账本表。

提示

LEDGER = ON 在账本数据库中创建可更新的账本表时是可选的。 默认情况下,账本数据库中的每个表都是可更新的账本表。

有关在 T-SQL 语句中指定 LEDGER 参数时可用选项的详细信息,请参阅 CREATE TABLE (Transact-SQL)

重要

创建账本表后,不能将其还原为不是账本表的表。 因此,攻击者无法在账本表上临时删除账本功能,进行修改,然后重新启用账本功能。

可更新账本表架构

可更新账本表需要具有以下 GENERATED ALWAYS 列,这些列包含元数据,说明哪些事务对表进行了更改,以及交易更新行的操作顺序。 此数据可用于取证目的,了解在一段时间内插入数据的方式。

如果未在 CREATE TABLE (Transact-SQL) 语句中指定账本表和账本历史记录表所需的 GENERATED ALWAYS 列,系统会自动添加这些列,并使用以下默认名称。 有关详细信息,请参阅创建可更新账本表中的示例。

默认列名称 数据类型 描述
ledger_start_transaction_id bigint 创建行版本的事务 ID
ledger_end_transaction_id bigint 删除行版本的事务 ID
ledger_start_sequence_number bigint 创建行版本的事务中的操作序列号
ledger_end_sequence_number bigint 删除行版本的事务中的操作序列号

历史记录表

创建可更新账本表时,将自动创建历史记录表。 历史记录表将捕获由于可更新账本表中的更新和删除操作而更改的行的历史值。 历史记录表的架构反映了与其关联的可更新账本表的架构。

创建可更新账本表时,可指定要包含历史记录表的架构的名称和历史记录表的名称,也可以让系统生成历史记录表的名称,并将其添加到与账本表相同的架构中。 具有系统生成的名称的历史记录表称为匿名历史记录表。 匿名历史记录表的命名约定为 <schema>.<updatableledgertablename>.MSSQL_LedgerHistoryFor_<GUID>

账本视图

对于每个可更新账本表,系统会自动生成一个名为“账本视图”的视图。 账本视图是可更新账本表及其关联的历史记录表的联接。 账本视图通过联接历史记录表中的历史数据,报告可更新账本表上发生的所有行修改。 该视图使用户、其合作伙伴或审核员可以分析所有历史操作并检测潜在的篡改。 每个行操作都伴随操作事务的 ID,以及操作是 DELETE 还是 INSERT。 用户可以检索有关执行事务的时间、执行此事务的用户标识的详细信息,并将其与此事务执行的其他操作关联起来。

例如,如果想要跟踪银行业务场景中的事务历史记录,账本视图将提供一段时间内的事务历史记录。 使用账本视图,无需单独查看可更新账本表和历史记录表,也无需为此构建自己的视图。

有关使用账本视图的示例,请参阅创建和使用可更新账本表

账本视图的架构将反映可更新账本和历史记录表中定义的列,但 GENERATED ALWAYS 列不同于可更新账本和历史记录表的列。

账本视图架构

注意

创建表时,可以将 <ledger_view_option> 参数和 CREATE TABLE (Transact-SQL) 语句配合使用来自定义账本视图的列名称。 有关详细信息,请参阅 CREATE TABLE (Transact-SQL) 中的账本视图选项和相应的示例。

默认列名称 数据类型 描述
ledger_transaction_id bigint 创建或删除行版本的事务 ID。
ledger_sequence_number bigint 表中事务内的行级别操作的序列号。
ledger_operation_type tinyint 包含 1 (INSERT) 或 2 (DELETE)。 在账本表中插入行会在此列包含 1 的账本视图中生成一个新行。 从账本表中删除行会在此列包含 2 的账本视图中生成一个新行。 更新账本表中的行在账本视图中生成两个新行。 在此列中,一行包含 2(DELETE),另一行包含 1(INSERT)
ledger_operation_type_desc nvarchar(128) 包含 INSERTDELETE。 有关详细信息,请参阅上一行。