我们正在使用“每个受监控表的 1 个审计表”设计;但是,在我们的例子中,emp(PARENT)
表有一个子表emp_address
也需要监控,所以我们有emp_audit
and emp_addr_audit tables
。
postgres 审计 SQL:如何连接 PARENT 和 CHILD 表以进行报告。
/* Employee table */
create table emp (
emp_id integer primary key,
empnum integer,
empname varchar(50),
);
/* Address table */
create table emp_addr (
addr_id integer primary key,
emp_id integer, -- references table emp
line1 varchar(30),
);
/* Audit table for emp table */
create table emp_audit (
operation character(1),
emp_id integer,
empnum integer,
empname varchar(50),
updatetime timestamp,
txid bigint
);
/* Audit table for emp_addr table */
create table emp_addr_audit (
operation character(1),
addr_id integer,
emp_id integer,
line1 varchar(30),
updatetime timestamp,
txid bigint
);
我们使用 hibernate(java) 进行持久化,hibernate 只更新那些在更新操作中修改了列的表。鉴于此,我可能在 emp_addr_audit 表中有多个(比如 5)行,而 emp_audit 表中有 1 行。反之亦然。
每个事务(修改)报告需要 1 行。该报告将包含以下列
empname、line1、操作(插入/删除/更新)、更新时间
让我们考虑 2 个场景来了解需要什么:
- 在初始事务中,仅
emp
创建属性。然后在一个单独的事务中,创建相应的行emp_addr
。所以,现在,我们在表格中有 1 行,在emp_audit
表格中有 1 行emp_addr_audit
。该报告将有 2 行(每笔交易一行)。 emp
和属性都是emp_addr
在单个事务中创建的。这将确保 1 行 inemp_audit
和 1 行 inemp_addr_audit
。现在,报告将只有 1 行(因为两个表行都是在单个事务中创建的)。
场景:
事务 #1:我在 emp 和 emp_addr 中都插入了一行。这导致 emp_audit 和 emp_addr_audit.(INSERT)
Transaction #2 中各有一行:我更新了上面的 emp' 属性。这会在 emp_audit 中产生一个 UPDATE 行。
事务 #3:我更新了上述 emp_addr 的属性。这会在 emp_addr_audit 中产生一个 UPDATE 行。
我尝试了以下 SQL #1,它返回了 3 行(如预期的那样);
SQL #1
SELECT emp.*, addr.*
FROM emp_audit emp
FULL OUTER JOIN emp_addr_audit addr USING(emp_id, txid);
但是,当我where
在 SQL 中添加一个子句时,它只返回 2 行。丢失的行是事务 #3 的结果,其中只有 emp_addr 表行已更新,而 emp 表行未受影响。
SQL #2
SELECT emp.*, addr.*
FROM emp_audit emp
FULL OUTER JOIN emp_addr_audit addr USING(emp_id, txid);
WHERE emp.empnum = 20;
什么 SQL仍然能够为 3 个事务获取 3 行,以便我仍然可以根据 empnum 过滤掉?