「監視対象テーブルごとに 1 つの監査テーブル」設計を使用しています。ただし、この場合、テーブルには監視する必要がemp(PARENT)
ある子テーブルがあるため、 と があります。emp_address
emp_audit
emp_addr_audit tables
postgres audit 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, operation(insert/delete/update), updatetime
何が必要かを理解するために、2 つのシナリオを考えてみましょう。
- 最初のトランザクションでは、
emp
属性のみが作成されます。次に、別のトランザクションで、対応する行emp_addr
が作成されます。これで、emp_audit
テーブルに 1 行、テーブルに 1 行ができましたemp_addr_audit
。レポートには 2 行 (トランザクションごとに 1 行) があります。 emp
と属性の両方emp_addr
が 1 つのトランザクションで作成されます。これにより、 に 1 行、 に 1 行あることが保証さemp_audit
れemp_addr_audit
ます。これで、レポートには 1 行のみが表示されます (両方のテーブル行が 1 つのトランザクションで作成されたため)。
シナリオ:
トランザクション #1: emp と emp_addr の両方に行を挿入します。これにより、emp_audit と emp_addr_audit でそれぞれ 1 行になります。(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;
empnumに基づいて除外できるように、3 つのトランザクションに対して 3 つの行を取得できるSQL は何ですか?