通用数据库设计 - 我可以在其他表中引用字段名称

ale*_*ale 4 sql database oracle audit database-design

我有一个表格,其中包含可以更新的各种字段.我们称之为table1并假设它具有以下字段:

user VARCHAR2
first_name VARCHAR2
last_name VARCHAR2
Run Code Online (Sandbox Code Playgroud)

我的问题:我想跟踪对这些字段的编辑.我有一个应用程序,允许这些字段进行更新,但我想跟踪的一个字段编辑,编辑的字段,场被编辑-的是我需要帮助的位.

我可以有一个历史表:

date_edited DATE
who_edited VARCHAR2
field_name_edited VARCHAR2
Run Code Online (Sandbox Code Playgroud)

如果字段名称改变了怎么办?这意味着field_name_edited它将引用一个不存在的字段.这似乎是一种愚蠢的做法.

做这种事必须有一些常见的方法吗?

非常感谢.

编辑

我使用的是Oracle DB - 请参阅新的问题标签.

APC*_*APC 6

"必须有一些常见的方法来做这种事情?"

不是真的,因为你的方法是一个常见但被误导的方法.由于以下几个原因,列级别的跟踪更改不能令人满意:

  1. 当更新触及多个列(为每个更新的行插入多个审计记录)时,它会变得昂贵.
  2. 很难在给定的时间点汇编记录状态的连贯图片(编程复杂,启动成本更高).
  3. 没有优雅的方法来测试给定的列是否已被更改.
  4. 存储列值很麻烦(实现通常通过将它们转换为字符串来处理不同的数据类型).

(您建议的表格不涉及最后一点,我认为这是一个疏忽:对跟踪更改值的审计跟踪没什么价值).

那么,常见的解决方案是什么?行级历史表.使用触发器将整个记录插入到日志记录表中(与DATE_EDITED和WHO_EDITED等元数据列一起).可以从数据字典轻松生成这些触发器.

确实,这种方法使得在任何给定的事务中更难发现编辑哪些列.然而:

  1. 这很难但并非不可能.它可以在SQL中实现(使用分析LAG或其他东西),但实际上人类非常擅长于独立发现变化.
  2. 这个成本由审计子系统承担,在现实生活中 - 无论要求是什么 - 都不会被大量使用,当然也不会比应用程序的核心部分少得多.因此,最好将处理成本转移到审计子系统,而不是使日记费用昂贵.

而且,正如我所说,在生成审计记录和检索审计记录时,行级日志记录的成本低于列级别.


在您的评论中,您链接到有关Oracle的Total Recall产品的文章.这实际上是一个非常优雅的解决方案,它对主系统的影响非常小,并且可以轻松恢复表的历史状态.问题是,在12c之前,它是企业版的一个额外收费,这使得它很昂贵.(事实上​​,它现在是Advanced Compression选项的一部分,而不是单独的产品).在12c基本闪回数据存档(Total Recall的新名称)可用于所有版本,但我们仍需要购买高级压缩选项来压缩日志表.


"你建议[存储]行编辑,从而存储冗余和数据."

是的.这些天存储通常很便宜.存储冗余数据的成本通常是为有效写入和检索记录而付出的代价.

"你仍然需要复制原始列的文字名称"

Journalling为每个数据表使用一个审计表; 审计表与实时表的结构相匹配,还有一些附加列用于保存与事务相关的元数据.我们希望审计列与其类似数据列具有相同的名称.(做其他事情会很愚蠢,尤其是因为我们可以从数据字典中为审计表生成DDL.)