每次我需要设计一个新的数据库时,我都要花费相当多的时间来思考应该如何设置数据库模式以保存更改的审计日志。
这里已经提出了一些关于这一点的问题,但我不同意有一个单一的最佳方法适用于所有场景:
我还偶然发现了这篇关于维护数据库更改日志的有趣文章,该文章试图列出每种方法的优缺点。 这篇文章写得很好,信息也很有趣,但它让我的决定变得更加困难。
我的问题是:是否有一个我可以使用的参考资料,也许是一本书或类似决策树之类的东西,我可以参考这些资料,根据一些输入变量来决定我应该走哪条路,比如:
我知道的方法有:
1.为创建和修改日期和用户添加列
表示例:
主要缺点:我们失去了修改的历史。 提交后无法回滚。
2.仅插入表格
表示例:
主要缺点:如何保持外键最新? 需要巨大的空间
3.为每个表创建一个单独的历史记录表
历史记录表示例:
主要缺点:需要复制所有审核过的表。 如果模式发生变化,也需要迁移所有日志。
4.为所有表创建一个统一的历史记录表
历史记录表示例:
主要缺点:如果需要,我是否能够轻松地重新创建记录(回滚)? new_value列需要是一个巨大的字符串,这样它才能支持所有不同的列类型。
一些wiki平台使用的一种方法是将识别数据和您正在审核的内容分开。 它增加了复杂性,但最终得到的是完整记录的审计跟踪,而不仅仅是编辑过的字段列表,您必须将这些字段列表拼凑起来,以便让用户了解旧记录的样子。
例如,如果您有一个名为Opportunities的表来跟踪销售交易,则实际上需要创建两个单独的表:
机遇
Opportunities_Content(或类似内容)
Opportunities表将包含用于唯一标识记录的信息,并包含用于外键关系的主键。 Opportunities_Content表将保存用户可以更改的所有字段,并且您希望对这些字段保留审核跟踪。 内容表中的每个记录将包括其自己的主键以及修改人和修改日期数据。 机会表将包括对当前版本的引用,以及关于主记录最初创建的时间和由谁创建的信息。
下面是一个简单的例子:
CREATE TABLE dbo.Page(
ID int PRIMARY KEY,
Name nvarchar(200) NOT NULL,
CreatedByName nvarchar(100) NOT NULL,
CurrentRevision int NOT NULL,
CreatedDateTime datetime NOT NULL
和内容:
CREATE TABLE dbo.PageContent(
PageID int NOT NULL,
Revision int NOT NULL,
Title nvarchar(200) NOT NULL,
User nvarchar(100) NOT NULL,
LastModified datetime NOT NULL,
Comment nvarchar(300) NULL,
Content nvarchar(max) NOT NULL,
Description nvarchar(200) NULL
如果Revision是标识类型,我可能会将contents表的PK设置为来自PageID和Revision的多列键。 您将使用修订列作为FK。 然后,您通过如下方式连接来拉出合并记录:
SELECT * FROM Page
JOIN PageContent ON CurrentRevision = Revision AND ID = PageID
上面可能有些错误。。。这是我无法想象的。 不过,它应该会让您对另一种模式有一个概念。
如果您正在使用SQL Server2008,则可能应该考虑变更数据捕获。 这是2008年的新产品,可以为您节省大量的工作。
我不知道有什么参考资料,但我肯定有人写过什么。
但是,如果目的只是简单地记录所发生的事情--审计日志的最典型用途--那么为什么不简单地保留所有内容:
timestamp
username
ip_address
procedureName (if called from a stored procedure)
database
table
field
accesstype (insert, delete, modify)
oldvalue
newvalue
这大概是由一个触发器维持的。