【发布时间】:2011-04-19 22:42:52
【问题描述】:
我们使用"1 audit table for each monitored Table" 设计;然而,在我们的例子中,emp(PARENT) 表有一个子表emp_address,它也需要被监控,所以我们有emp_audit 和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_audit 表中的 1 行,我可能在 emp_addr_audit 表中有多个(比如 5)行。反之亦然。
每个交易(修改)报告需要 1 行。 该报告将包含以下列
empname、line1、操作(插入/删除/更新)、更新时间
让我们考虑 2 个场景来了解需要什么:
- 在初始事务中仅创建
emp属性。然后在单独的事务中,创建emp_addr中的相应行。所以,现在,emp_audit表中有 1 行,emp_addr_audit表中有 1 行。该报告将有 2 行(每笔交易各一行)。 -
emp和emp_addr属性均在单个事务中创建。这将确保emp_audit中有 1 行,emp_addr_audit中有 1 行。现在,报告将只有 1 行(因为两个表行都是在单个事务中创建的)。
场景:
事务 #1:我在 emp 和 emp_addr 中都插入了一行。这会在 emp_audit 和 emp_addr_audit 中各产生一行。(INSERT)
事务 #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);
但是,当我在 SQL 中添加 where 子句时,它只返回 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 过滤掉?
【问题讨论】:
-
那么,你想加入
employee audit和employee address吗? -
抱歉给您带来了困惑。我修复了错误。我正在尝试将 emp_audit 与 emp_addr_audit 一起加入。
标签: sql postgresql parent-child audit full-outer-join