7

对于我正在处理的一个项目,我被要求创建对记录所做的所有更改的审计跟踪。这是我第一次不得不创建审计跟踪,所以我一直在做很多关于这个主题的研究。

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

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

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

  1. 能够查看对字段所做的所有更改的日志(我几乎知道如何执行此操作)

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

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

4

3 回答 3

4

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

要求 #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'

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

于 2009-07-01T22:10:48.073 回答
2

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

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

我认为您准备某种 aggregateOfTheAuditTrail 数据的想法可能非常有用。问题是每条记录一个标志是否足够?如果用户的主要访问权限是通过列表,那么仅突出显示更改的记录以供以后深入研究就足够了。或者记录值的最后更改日期,以便仅突出显示最近更改的记录 - 全部回到用户的实际需求。我发现很难想象 3 年前更改的记录与上周更改的记录一样有趣。

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

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

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

于 2009-07-01T22:22:17.253 回答
0

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

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

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

这是假设表的结构不会随着时间而改变(关于数据列的数量)

对于更新,只需插入

'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”已插入和更新,其中他们的部门已更新。

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

于 2009-07-01T22:31:57.483 回答