Db 行更改的审核历史记录
Audit history for changes in Db Row
场景:
我有一个数据库 table,此 table 的任何列的任何数据更改都需要进行审核记录以供比较。
我试过的:
我有一个历史 table 与父 table 具有相同的值列,并且对数据库的任何更改都会使用触发器记录到新的 table 中,我最终实现了我要。
问题
问题是多方面的:
- 我正在使用我不想使用的触发器。
- 如果我必须对 n 个以上的 table 进行审计比较,那么我需要每个父 table 有一个历史记录 table,这只会膨胀我的数据库并使其成为有这么多 tables.
是否有更好的实现方法,请提出建议?
答案与您的业务或领域逻辑位置密切相关。
如果你的业务逻辑在你的数据库中(stored procedures
和triggers
)那么,我觉得你的做法是让数据库triggers
写入相关审计tables.
I am using triggers which I do not want to use.
审计方法:
如果您的领域逻辑在 c#
代码中的 领域层 中,那么您说您不希望审计成为在 triggers
。在 域层 和 数据库 之间混合业务逻辑可能会导致维护噩梦 o_O
假设您的逻辑位于 域层 :一个想法是为您的域或服务设置一个 base class
来处理写入审计跟踪:
public class DomainBase<T>
{
public DomainBase(bool isAuditEnabled)
{
this.IsAuditEnabled = isAuditEnabled;
}
public bool IsAuditEnabled { get; set; }
public void AddNew(T newEntity)
{
// default code for adding an entity
this.Audit_Create(newEntity);
}
public void Audit_Create(T newEntity)
{
if (IsAuditEnabled)
{
// ...
}
}
}
您的 base class
可以有标准的 AddNew
、Update
、Delete
方法,这些方法依次调用相关的 Audit 方法。然后,您可能还需要考虑一个 IsAuditEnabled
开关,以允许您轻松地打开 on/off 特定审计。这样您就可以只审核您关心的更改,而不审核其他任何内容。
每个自定义 domain 方法都可以选择是否写入审计跟踪。这也是为什么在您的方案中 不是 将审计跟踪放在 DAL
(数据访问层)中的好主意,因为 业务逻辑 决定 if 和 what 必须被审计,并且 DAL
不应该做出这些类型的逻辑决定。
If I have to have audit comparison for n more tables, then I need to
have one history table per parent table and which just swells my
database and makes it bulky with so many tables.
关注的数据库大小
- 如前所述,仅审核您需要的内容会减少
审计数据写入。
- 如果审计数据太多或增长太快,您可以选择单独的审计数据库。这样您的 生产数据库 保持轻量级和优化,并且您只能在 罕见 情况下(希望如此)查询审计数据库。通过这种方式,您可以 BIG 并审计所有移动的生命周期而不用担心性能(甚至不在审计数据库中包含
indexes
以允许快速高效写)。
- 此外,如果您并不真正关心 table 中的所有数据,您可以创建仅包含 重要[=67= 字段的审计 table ] 给你。因此,您最终可能会得到 50 列的 table,仅审核 5 或 10 列,这些列对于历史目的至关重要。
场景:
我有一个数据库 table,此 table 的任何列的任何数据更改都需要进行审核记录以供比较。
我试过的:
我有一个历史 table 与父 table 具有相同的值列,并且对数据库的任何更改都会使用触发器记录到新的 table 中,我最终实现了我要。
问题
问题是多方面的:
- 我正在使用我不想使用的触发器。
- 如果我必须对 n 个以上的 table 进行审计比较,那么我需要每个父 table 有一个历史记录 table,这只会膨胀我的数据库并使其成为有这么多 tables.
是否有更好的实现方法,请提出建议?
答案与您的业务或领域逻辑位置密切相关。
如果你的业务逻辑在你的数据库中(stored procedures
和triggers
)那么,我觉得你的做法是让数据库triggers
写入相关审计tables.
I am using triggers which I do not want to use.
审计方法:
如果您的领域逻辑在 c#
代码中的 领域层 中,那么您说您不希望审计成为在 triggers
。在 域层 和 数据库 之间混合业务逻辑可能会导致维护噩梦 o_O
假设您的逻辑位于 域层 :一个想法是为您的域或服务设置一个 base class
来处理写入审计跟踪:
public class DomainBase<T>
{
public DomainBase(bool isAuditEnabled)
{
this.IsAuditEnabled = isAuditEnabled;
}
public bool IsAuditEnabled { get; set; }
public void AddNew(T newEntity)
{
// default code for adding an entity
this.Audit_Create(newEntity);
}
public void Audit_Create(T newEntity)
{
if (IsAuditEnabled)
{
// ...
}
}
}
您的 base class
可以有标准的 AddNew
、Update
、Delete
方法,这些方法依次调用相关的 Audit 方法。然后,您可能还需要考虑一个 IsAuditEnabled
开关,以允许您轻松地打开 on/off 特定审计。这样您就可以只审核您关心的更改,而不审核其他任何内容。
每个自定义 domain 方法都可以选择是否写入审计跟踪。这也是为什么在您的方案中 不是 将审计跟踪放在 DAL
(数据访问层)中的好主意,因为 业务逻辑 决定 if 和 what 必须被审计,并且 DAL
不应该做出这些类型的逻辑决定。
If I have to have audit comparison for n more tables, then I need to have one history table per parent table and which just swells my database and makes it bulky with so many tables.
关注的数据库大小
- 如前所述,仅审核您需要的内容会减少 审计数据写入。
- 如果审计数据太多或增长太快,您可以选择单独的审计数据库。这样您的 生产数据库 保持轻量级和优化,并且您只能在 罕见 情况下(希望如此)查询审计数据库。通过这种方式,您可以 BIG 并审计所有移动的生命周期而不用担心性能(甚至不在审计数据库中包含
indexes
以允许快速高效写)。 - 此外,如果您并不真正关心 table 中的所有数据,您可以创建仅包含 重要[=67= 字段的审计 table ] 给你。因此,您最终可能会得到 50 列的 table,仅审核 5 或 10 列,这些列对于历史目的至关重要。