前言

上一篇的 Soft Delete 后, 我们继续来看看 History Table (Audit/Archive Table).

Archive Table 市场上有了这样叫, 但我觉得它比较杂, 因为它既保存了 History, 也多少记入 operation 和时间, 所以带有一点 Audit 的味道.

我们姑且叫它 HIstory Table 就好呗.

上回说到我们的需求就是不希望任何数据被删除, 找不回来.

除了 Soft Delete, Temporal Table 能完成这个需求, 还有就是 History Table.

也就就是自己做一个 table 然后把所有 delete/update 移除的数据放以 json 的方式存进去. (和 temporal 差不多, 只是 temporal 是每一个表都一个 history table, 然后它不是 json 而是完整的表结构)

这个方案的优点就是没有 Temporal 那么重, 又比 Soft Delete 轻.

Step 1: Create History Table

大概长这样

Step 2: Trigger After Delete

GO
CREATE OR ALTER TRIGGER [TR_Country_AfterDelete_ForAuditData] ON [Country]
AFTER DELETE
AS
IF (ROWCOUNT_BIG() = 0) RETURN;
SET NOCOUNT ON; DECLARE @i int = 0, @count int;
SELECT @count = COUNT(*) FROM deleted;
DECLARE @dateCreated datetimeoffset(3) = CAST(SYSDATETIMEOFFSET() AT TIME ZONE 'Singapore Standard Time' AS datetimeoffset(3)); WHILE(@i < @count)
BEGIN
INSERT INTO AuditDataLog (TableName, Operation, DeletedDataJson, InsertedDataJson, DateCreated)
VALUES (
'Country',
'Delete',
(SELECT * FROM (SELECT * FROM deleted ORDER BY CountryId OFFSET @i ROWS FETCH NEXT 1 ROWS ONLY) Temp FOR JSON AUTO, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER),
NULL,
@dateCreated
);
SET @i += 1;
END
GO

要记得哦, deleted 是一个表, 里面会有很多 deleted rows 的. 这里把 deleted row 一条一条 insert 是为了以后方便 filter 查看. 但是会让性能慢的哦.

Step 3: Trigger After Update

和上面差不多, 只是多了一句 for inserted 而已.

GO
CREATE OR ALTER TRIGGER [TR_Country_AfterDelete_ForAuditData] ON [Country]
AFTER UPDATE
AS
IF (ROWCOUNT_BIG() = 0) RETURN;
SET NOCOUNT ON; DECLARE @i int = 0, @count int;
SELECT @count = COUNT(*) FROM deleted;
DECLARE @dateCreated datetimeoffset(3) = CAST(SYSDATETIMEOFFSET() AT TIME ZONE 'Singapore Standard Time' AS datetimeoffset(3)); WHILE(@i < @count)
BEGIN
INSERT INTO AuditDataLog (TableName, Operation, DeletedDataJson, InsertedDataJson, DateCreated)
VALUES (
'Country',
'Update',
(SELECT * FROM (SELECT * FROM deleted ORDER BY CountryId OFFSET @i ROWS FETCH NEXT 1 ROWS ONLY) Temp FOR JSON AUTO, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER),
(SELECT * FROM (SELECT * FROM inserted ORDER BY CountryId OFFSET @i ROWS FETCH NEXT 1 ROWS ONLY) Temp FOR JSON AUTO, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER),
@dateCreated
);
SET @i += 1;
END
GO

题外话:

本来想把这个表叫 AuditDataLog 的, 但由于 deleted 没有办法记入 DeletedBy (除非搞一些 stored procedure)

所以还是把它定位为 History Table 就好了. 如果想知道是谁 delete 了, 那么这里获取到时间后, 在去查 Audit Api Log, 有了时间范围, 要找出谁 performance 了相关 action 就容易多了.

SQL Server – History Table (Audit/Archive Table)的更多相关文章

  1. SQL Server数据恢复准备之TRUNCATE TABLE理解

    SQL Server数据恢复准备之TRUNCATE TABLE理解 转自:https://blog.51cto.com/aimax/2142553 易语随风去关注0人评论6717人阅读2018-07- ...

  2. SQL Server 查看分区表(partition table)的分区范围(partition range)

    https://www.cnblogs.com/chuncn/archive/2009/02/20/1395165.html SQL Server 2005 的分区表(partition table) ...

  3. SQL Server 审计(Audit)

    审计(Audit)用于追踪和记录SQL Server实例,或者单个数据库中发生的事件(Event),审计运作的机制是通过捕获事件(Event),把事件包含的信息写入到事件日志(Event Log)或审 ...

  4. 1 SQL SERVER 实现字符串分割成table的方法

    CREATE FUNCTION [dbo].[fn_SplitStringToTable] ( @p_Input VARCHAR(MAX), @p_Delimeter CHAR() = ',' ) R ...

  5. Sql Server中的表访问方式Table Scan, Index Scan, Index Seek

    1.oracle中的表访问方式 在oracle中有表访问方式的说法,访问表中的数据主要通过三种方式进行访问: 全表扫描(full table scan),直接访问数据页,查找满足条件的数据 通过row ...

  6. 转:Sql Server中的表访问方式Table Scan, Index Scan, Index Seek

    0.参考文献 Table Scan, Index Scan, Index Seek SQL SERVER – Index Seek vs. Index Scan – Diffefence and Us ...

  7. P6 Professional Installation and Configuration Guide (Microsoft SQL Server Database) 16 R1

    P6 Professional Installation and Configuration Guide (Microsoft SQL Server Database) 16 R1       May ...

  8. SQL Server表和字段说明的增加和更新

    1. 增加字段说明 EXEC sp_addextendedproperty     'MS_Description',     'some description',     'user',      ...

  9. SQL SERVER临时表的使用

    SQL SERVER临时表的使用 drop table #Tmp   --删除临时表#Tmpcreate table #Tmp --创建临时表#Tmp(    ID   int IDENTITY (1 ...

  10. Microsoft SQL Server Version List [sqlserver 7.0-------sql server 2016]

    http://sqlserverbuilds.blogspot.jp/   What version of SQL Server do I have? This unofficial build ch ...

随机推荐

  1. Curve 进入 CNCF Sandbox,完善统一云原生开源存储拼图

    2022 年 6 月 15 日,云原生计算基金会 (CNCF) 宣布,分布式存储系统 Curve 被正式接纳为 CNCF 沙箱(Sandbox)项目.Curve 由网易数帆开源,提供块存储和文件存储能 ...

  2. Java JVM——12. 垃圾回收理论概述

    1.前言 1.1 什么是垃圾? 在提到什么是垃圾之前,我们先看下面一张图: 从上图我们可以很明确的知道,Java 和 C++ 语言的区别,就在于垃圾收集技术和内存动态分配上,C++ 语言没有垃圾收集技 ...

  3. AT_arc111_a 题解

    洛谷连接&Atcoder 链接 题目简述 给定两个数 \(n\) 和 \(m\),输出 \(\left\lfloor\frac{10^n}{m}\right\rfloor \bmod m\) ...

  4. .NET TCP、UDP、Socket、WebSocket

    做.NET应用开发肯定会用到网络通信,而进程间通信是客户端开发使用频率较高的场景. 进程间通信方式主要有命名管道.消息队列.共享内存.Socket通信,个人使用最多的是Sokcet相关. 而Socke ...

  5. 写几个有用的lambda

    List<String> list = Arrays.asList("app", "ban", "ora"); //循环输出 f ...

  6. 【JDBC】Extra03 PostgreSQL-JDBC

    PostgreSQL的JDBC实现: <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql --> <d ...

  7. 【Lodop】01 Lodop手册阅读上手

    官方网站: http://www.c-lodop.com/index.html 版本:6.2.2.6 一.概述 Lodop是一款用于WEB打印开发的专业WEB打印控件 控件发布包有3个系统文件组成,主 ...

  8. 常回家看看之fastbin_attack

    常回家看看之fastbin_attack 原理分析 fastbin属于小堆块的管理,这里说的fastbin_attack大多指glibc2.26之前的手法,因为自glibc2.26以后,glibc迎来 ...

  9. kimchi – kvm虚拟机网页管理

    参考: https://mangolassi.it/topic/15882/kimchi-kvm-updated-and-better-and-easy-guide-for-kvm-beginners ...

  10. 如何在 Ubuntu18.04 server 服务器版本的操作系统下 配置IP

    如题,现有需求,为一个server版本的Ubuntu18.04配置 IP . 在网上查到了     Ubuntu18.04  桌面版本  的配置方法: https://www.cnblogs.com/ ...