对于我正在从事的一个项目,我被要求创建对记录所做的所有更改的审计跟踪。这是我第一次必须创建审计跟踪,因此我对此主题进行了大量研究。

该应用程序将使用 PHP/MSSQL 开发,并且流量较低。

根据我的阅读,我几乎决定拥有一个审计表并使用触发器来记录表中的更改。

应用程序中显示的两个要求如下:

  1. 能够查看对字段所做的所有更改的日志(我几乎知道如何做到这一点)

  2. 在应用程序中查看记录时,能够看到记录中曾经更改过的任何字段旁边的指示符(可能还有其他信息,例如上次更改的日期)。

第#2 项是目前让我感到悲伤的一项。如果没有对每个字段进行单独的查询(或者需要很长时间才能执行的非常长的嵌套查询),是否有人对执行此操作的最佳方法有建议?(我曾考虑为表中的每个字段添加一个额外的“ModifiedFlag”字段,如果该字段曾经被编辑过,它将充当布尔指示器,但这似乎是很大的开销。

有帮助吗?

解决方案

我会尽可能将审计信息与实际域信息分开处理。

要求#1:我认为您将创建额外的审核表来记录更改。Eric 的建议是一个很好的建议,使用 SQL 数据库中的触发器创建审计信息。这样您的应用程序就不需要了解审核逻辑。

如果您的数据库不支持触发器,那么您可能正在使用某种持久性或数据库层。这也是放置这种逻辑的好地方,因为您可以再次最小化之间的任何依赖关系 普通的 应用程序代码和审计代码。

要求#2:至于显示指标:我不会在存储实际值的表中创建布尔字段。(这将导致您的系统之间存在各种依赖关系 普通的 应用程序代码和您的 审计追踪 代码。)

我会尝试让负责显示表单的代码也负责显示字段级别的审计数据。这会导致查询开销,但这就是显示这层额外信息的成本。也许您可以通过将元数据添加到审计信息中以方便检索,从而最大限度地减少数据库开销。

我维护的一些大型企业应用程序大致使用以下结构:

  • 与表中记录的更改相对应的更改头表。

领域:

changeId, changeTable, changedPrimaryKey, userName, dateTime

- 与被改变的字段对应的改变字段表。

领域:

changeId, changeField, oldValue, NewValue

样本内容:

改变标题:

'1', 'BooksTable', '1852860138', 'AdamsD', '2009-07-01 15:30'

更改项目:

'1', 'Title', 'The Hitchhiker's Guide to the Gaxaly', 'The Hitchhiker's Guide to the Galaxy'
'1', 'Author', 'Duglas Adasm', 'Douglas Adams'

这种结构既可以轻松查看审计跟踪,也可以轻松检索以显示所需的指标。一个查询(标题和项目表中的内部联接)足以检索所有信息以在单个表单中显示。(或者当您有显示的 ID 列表时甚至是一个表格)

其他提示

作为一般要求,标记已更改的字段“闻起来”有点奇怪。如果记录寿命很长并且会随着时间的推移而变化,那么最终所有字段都会被标记。因此,我想知道用户如何理解每个字段的一组简单指标。

这种思路让我怀疑,正如您所描述的,您存储的数据需要成为记录所有更改的真实审计跟踪,而第一个真正的挑战是决定如何向用户呈现信息。

我认为您准备某种aggregateOfTheAuditTrail 数据的想法可能非常有用。问题是每条记录有一个标志就足够了吗?如果用户的主要访问是通过列表,那么也许只需突出显示更改的记录以供以后深入查看就足够了。或者记录值最后一次更改的日期,以便仅突出显示最近更改的记录 - 一切都回到用户的真正需求。我很难想象三年前改变的记录和上周改变的记录一样有趣。

然后当我们深入到单个记录时。同样,每个字段的简单标志听起来没什么用(尽管您的域,您的要求)。如果是的话,那么你的总结想法就很好。我的猜测是,对字段的一系列更改以及对记录的整体更改序列要有趣得多。员工加薪、员工调动部门、员工升职=三起独立的业务事件还是一件?

如果需要的不仅仅是一个简单的标志,那么我怀疑您只需要返回整个(或最近的)审计跟踪以进行记录,并让 UI 弄清楚如何呈现它。

所以,我最初的想法是:对摘要记录进行某种滚动维护听起来是个好主意。如有必要,在后台线程或批处理作业中维护。我们将其设计为对业务有用,而无需每次都进行完整的审计跟踪。然后,为了进行详细分析,我们允许检索部分或全部踪迹。

就我个人而言,我会让跟踪变得简单,而报告变得时髦。

每次用户插入一条记录时,您都会在该表的审计表中插入一条记录

'I', 'Date', 'User', 'Data column1','Data Column2', etc.

这是假设表的结构不会随着时间的推移而改变(re.数据列的数量)

对于更新,只需插入

'U', 'Date', 'User', 'Data column1', etc

插入用户刚刚输入的内容作为更新。

然后,插入和更新后,您将得到以下内容

'I','May 3 2009','BLT','person005','John','Smith','Marketing'
'U','May 4 2009','BLT','person005','John','Smith','Accounting'

然后,这只是一个简单的报告,显示唯一的人员记录“person005”已进行插入和更新,其中更新了他们的部门。

由于系统的使用率较低,在更改时进行简单的插入然后进行更复杂的报告流程不会影响性能。这种风格仍然适用于较高流量的系统,因为编辑的额外负载很小,而报告更改的较高强度工作负载并不像更新那样频繁地完成,因此系统不会崩溃。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top