ledger 表不能阻止 delete,但确保其留下不可篡改的加密证据:delete 触发逻辑删除,原行存入受哈希链保护的历史表,账本视图中 ledger_operation_type = 3 明确标识,且所有事务纳入数据库级摘要可离线验证。

Ledger 表本身不能阻止 DELETE 操作执行,但能确保任何 DELETE 都留下不可篡改的加密证据——只要用的是可更新账本表(WITH (LEDGER = ON)),SQL Server 就会自动把被删行的原始状态存入历史表,并在账本视图中生成带哈希链的完整操作记录。
为什么 DELETE 不会“消失”,而是被完整捕获
可更新账本表依赖时态表机制:DELETE 实际触发的是“逻辑删除”:原行数据被移入配套的历史表(如 MSSQL_TemporalHistoryFor_YourTable),同时主表中该行被物理移除。关键点在于:
- 历史表本身也是账本表的一部分,其内容受哈希链保护,DBA 无法静默修改或清空
- 系统自动生成的账本视图(如
YourTable_Ledger)包含ledger_start_transaction_id、ledger_end_transaction_id、ledger_operation_type等列,其中ledger_operation_type = 3明确标识该行为DELETE - 所有事务都参与数据库级摘要(
sys.database_ledger_transactions),摘要哈希可导出并离线验证
如何快速确认某次 DELETE 是否发生且未被掩盖
不需要翻日志或查备份,直接查账本视图即可定位和验证:
- 执行
SELECT * FROM dbo.YourTable_Ledger WHERE ledger_operation_type = 3查出所有删除记录 - 比对
ledger_start_transaction_id和sys.database_ledger_transactions.transaction_id,确认该事务是否存在于全局摘要中 - 调用
sys.fn_database_ledger_get_blockchain_digest获取当前摘要哈希,与上次审计时保存的哈希比对——不一致即说明中间有未授权变更
仅附加账本表(APPEND_ONLY = ON)不适用 DELETE 场景
如果你的目标是彻底禁用 DELETE(而不仅是留痕),那应该选仅附加账本表,但它有硬性限制:
- 建表时必须显式指定
WITH (LEDGER = ON, APPEND_ONLY = ON) - 它**不允许**
UPDATE或DELETE,只允许INSERT;一旦建好就无法降级或修改此属性 - 它不生成历史表,只生成含
ledger_start_transaction_id和ledger_sequence_number的账本视图,适合日志、事件流等写一次场景 - 若已有业务逻辑依赖
DELETE,强行改用仅附加模式会导致应用报错,需重构 DML 路径
容易被忽略的部署前提和权限细节
账本功能不是“开箱即用”的开关,漏掉任一环节都会让防篡改失效:
- 数据库必须启用 Ledger:创建时加
WITH LEDGER = ON,或用ALTER DATABASE ... SET LEDGER = ON(注意:SQL Server 2022 CU1+ 才支持对现有库启用) - 用户执行
DELETE不需要特殊权限,但验证账本完整性需要VIEW DATABASE STATE或CONTROL权限才能查sys.database_ledger_transactions和调用摘要函数 - 摘要默认不自动上传到 Azure Blob;如需长期存证,得手动配置
ALTER DATABASE SCOPED CONFIGURATION SET LEDGER_DIGEST_STORAGE = ON并提供存储凭据 -
TRUNCATE TABLE在账本表上被明确禁止,会直接报错,这点比DELETE更刚性——但别指望它替代账本,它是另一层防护
真正起作用的不是“阻止动作”,而是让任何动作都变成可验证、可举证、不可抵赖的链上事件。账本表的价值不在拦截,而在让恶意操作者知道:删了也白删,痕迹比数据活得更久。











