我需要创建一个数据库表来存储不同的更改日志/审核(添加,删除,修改等内容时)。我不需要存储特别详细的信息,因此我在考虑以下方面:
- id(用于事件)
- 触发它的用户
- 活动名称
- 事件描述
- 事件的时间戳
我在这里想念什么吗?显然,我可以继续改进设计,尽管我不打算使其变得复杂(为事件类型或诸如此类的东西创建其他表是不可能的,因为这对我来说很复杂)。
我需要创建一个数据库表来存储不同的更改日志/审核(添加,删除,修改等内容时)。我不需要存储特别详细的信息,因此我在考虑以下方面:
我在这里想念什么吗?显然,我可以继续改进设计,尽管我不打算使其变得复杂(为事件类型或诸如此类的东西创建其他表是不可能的,因为这对我来说很复杂)。
Answers:
在我正在从事的项目中,审核日志也从非常简约的设计开始,就像您描述的那样:
event ID
event date/time
event type
user ID
description
想法是相同的:保持简单。
但是,很快就发现这种简约的设计是不够的。典型的审核会引发如下问题:
Who the heck created/updated/deleted a record
with ID=X in the table Foo and when?
因此,为了能够快速回答此类问题(使用SQL),我们最终在审核表中增加了两列
object type (or table name)
object ID
到那时,我们的审核日志的设计才真正稳定下来(几年了)。
当然,最后的“改进”仅适用于具有代理键的表。但猜猜怎么了?我们所有值得审核的表都具有这样的键!
我们还将记录新旧值以及它们来自的列,以及在审计详细信息表中被审计表的主键。想想您需要审计表做什么?您不仅要知道谁进行了更改以及何时进行更改,而且还希望在发生重大更改时知道一种快速的方式将数据放回原处。
在设计时,应编写代码以恢复数据。当您需要恢复时,通常很着急,最好已经做好准备。
您可能还需要审核其他几项内容,例如表/列名称,进行更新的计算机/应用程序等等。
现在,这取决于您真正需要多少详细的审核以及什么级别。
我们开始构建自己的基于触发器的审核解决方案,我们想审核所有内容,并且手头有一个恢复选项。事实证明这太复杂了,因此我们最终对基于触发器的第三方工具ApexSQL Audit进行了反向工程,以创建我们自己的自定义解决方案。
提示:
包含之前/之后的值
包括3-4列用于存储主键(如果它是复合键)
如Robert所建议,将数据存储在主数据库之外
将大量时间花在准备报告上-尤其是可能需要恢复的报告
计划存储主机/应用程序名称–这对于跟踪可疑活动可能非常有用
我们表中的内容:
Primary Key
Event type (e.g. "UPDATED", "APPROVED")
Description ("Frisbar was added to blong")
User Id
User Id of second authoriser
Amount
Date/time
Generic Id
Table Name
通用ID指向表中已更新的行,并且表名是该表的名称(以字符串形式)。不是很好的数据库设计,但是非常有用。我们所有的表都有一个代理键列,因此效果很好。
通常,自定义审核(创建各种表)是一个不好的选择。可以禁用数据库/表触发器以跳过某些日志活动。自定义审核表可能被篡改。可能会发生异常,导致应用程序崩溃。更不用说设计健壮解决方案的困难。到目前为止,我在此讨论中看到一个非常简单的案例。您需要与当前数据库以及所有特权用户(DBA,Developers)完全隔离。每个主流的RDBMS都提供审计功能,即使DBA也无法禁用这些审计功能,并且会对其保密。因此,RDBMS供应商提供的审核功能必须是首选。其他选择是第三方交易日志读取器或自定义日志读取器,它将分解后的信息推送到消息传递系统中,最终以某种形式的Audit Data Warehouse或实时事件处理程序结束。综上所述:解决方案架构师/“动手实践数据架构师”需要参与根据需求设计这样的系统。通常,这些东西太严重了,以至于不能交给开发人员寻求解决方案。
有很多方法可以做到这一点。我最喜欢的方式是:
mod_user
在源表中添加一个字段(要记录的字段)。
创建一个日志表,其中包含要记录的字段以及log_datetime
和seq_num
字段。 seq_num
是主键。
在源表上构建触发器,只要更改任何受监视的字段,该触发器就会将当前记录插入日志表。
现在,您已获得每项更改及其更改记录。