【问题标题】:database audit table数据库审计表
【发布时间】:2010-12-14 20:00:12
【问题描述】:

我有一个正在使用的现有应用程序,并且客户已经定义了他们希望用于审计日志的表结构。它有以下列:

storeNo 
timeChanged
user 
tableChanged 
fieldChanged 
BeforeValue 
AfterValue

通常我在每个表上都有简单的审计列,提供 userChanged 和 timeChanged 值。将写入这些表的应用程序是一个 java 应用程序,调用是通过 jdbc 在 oracle 数据库上进行的。我的问题是获得之前/之后值的最佳方法是什么。我讨厌比较对象以查看为填充此表所做的更改,这不会有效。如果在一次更新中更改了多个列,则此新表将具有多个条目。或者有没有办法在oracle中做到这一点?过去其他人做了什么来不仅跟踪变化,而且跟踪变化的价值观?

【问题讨论】:

    标签: java oracle audit


    【解决方案1】:

    这通常是 oracle 触发器的用途。每次插入或更新都会触发一个存储过程,该过程可以访问“之前和之后”数据,您可以随意使用这些数据,例如将旧值记录到审计表中。它对应用程序是透明的。

    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:59412348055

    【讨论】:

    • 如果可以的话,我会给你一百万票。您不能从应用程序中执行此操作,它必须在触发器中,否则您将无法捕获所有更改。
    • 如果您知道所有数据库更新都通过应用程序进行,并且您的应用程序使用有竞争力的 ORM 层,那么可能是 ORM 层版本控制可以完成这项工作也。
    • 该死的。打败我。 +1 为 TFGITW :)
    • WW: 一个不错的 ORM 层应该内置某种形式的乐观锁定,这样如果记录在被 ORM 拾取后发生了变化,它不会盲目地用它的想法覆盖它什么是最新和最大的价值观。因此,只有当 ORM 知道前后值是什么时,它才应该进行更新。
    • @Gary,通常乐观锁定是使用并发令牌实现的,而不是通过缓存所有值并比较它们。
    【解决方案2】:

    我将同上触发器。

    如果您必须在应用程序级别执行此操作,如果不执行这些步骤,我看不出怎么可能:

    1. 开始交易
    2. SELECT FOR UPDATE 要更改的记录
    3. 对于每个要更改的字段,从记录中提取旧值,从程序逻辑中提取新值
    4. 为每个要更改的字段,编写审计记录
    5. 更新记录
    6. 结束交易

    如果有很多这种情况,我想我会创建一个更新记录函数来进行比较,无论是在通用级别还是在每个表的单独函数中。

    【讨论】:

      【解决方案3】:

      “客户已经为审计日志定义了他们想要的表结构”

      可怕的词。

      您将如何实现这样的事情:

      create or replace trigger emp_bur before insert on emp for each row
      begin
          if :new.ename = :old.ename then
              insert_audit_record('EMP', 'ENAME', :old.ename, :new.ename);
          end if;
          if :new.sal = :old.sal then
              insert_audit_record('EMP', 'SAL', :old.sal, :new.sal);
          end if;
          if :new.deptno = :old.deptno then
              insert_audit_record('EMP', 'DEPTNO', :old.deptno, :new.deptno);
          end if;
      end;
      /
      

      如您所见,它涉及大量重复,但这很容易处理,代码生成器构建在数据字典之上。但这种方法存在更严重的问题。

      1. 它有相当大的开销:一个 单次更新触及十 字段将生成十个插入 声明。
      2. BeforeValue 和 AfterValue 当我们 必须处理不同的数据类型 - 甚至日期和时间戳变成 有趣,更不用说 CLOB。
      3. 很难重构状态 在某个时间点的记录。我们 需要从最早开始 版本的记录并应用 随后的变化逐渐增加。
      4. 目前还不是很明显 这种方法将处理 INSERT 和 DELETE 语句。

      现在,如果客户的基本要求是监控对少数敏感列的更改:EMPLOYEES.SALARY、CREDIT_CARDS.LIMIT 等,那么这些反对意见都不是问题。但如果要求是监控每个表的更改, “整条记录”方法更好:只需为受 DML 影响的每一行插入一条审计记录。

      【讨论】:

        【解决方案4】:

        如果您使用 Oracle 10g 或更高版本,您可以使用内置的审计功能。您为许可证支付了很多钱,不妨使用它。

        阅读更多http://www.oracle.com/technology/pub/articles/10gdba/week10_10gdba.html

        【讨论】:

        • 细粒度审计需要企业版许可证,但并非所有人都喜欢。但我同意,如果我们已经为 EE 许可证付费,那么我们应该使用内置插件,而不是自己滚动。
        猜你喜欢
        • 2011-03-17
        • 2017-08-25
        • 2012-10-27
        • 1970-01-01
        • 2015-02-15
        • 2017-12-19
        • 2012-05-30
        • 2014-02-06
        • 2015-11-26
        相关资源
        最近更新 更多