Мы используем "1 таблица аудита для каждой отслеживаемой таблицы" design;Однако в нашем случае таблица emp(PARENT)
имеет дочернюю таблицу emp_address
, которую также необходимо отслеживать, поэтому у нас есть emp_audit
и emp_addr_audit tables
.
SQL аудита postgres: как объединить 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 только для тех таблиц, столбцы которых были изменены в операции обновления.Учитывая это, у меня может быть несколько (скажем, 5) строк в таблице emp_addr_audit на 1 строку в таблице emp_audit.И наоборот.
В отчете требуется 1 строка для каждой транзакции (модификации).Отчет будет иметь следующие столбцы
empname, строка1, операция (вставка / удаление / обновление), время обновления
Давайте рассмотрим 2 сценария, чтобы понять, что необходимо:
- В исходной транзакции создаются только
emp
атрибуты.Затем в отдельной транзакции создается соответствующая строка в emp_addr
.Итак, теперь у нас есть 1 строка в таблице emp_audit
и 1 строка в таблице emp_addr_audit
.Отчет будет иметь 2 строки (по одной на каждую транзакцию). - Оба атрибута
emp
и emp_addr
создаются в одной транзакции.Это обеспечит наличие 1 строки в emp_audit
и 1 строки в emp_addr_audit
.Теперь отчет будет иметь ТОЛЬКО 1 строку (поскольку обе строки таблицы были созданы в одной транзакции).
Сценарий :
Транзакция # 1: я вставляю строкув обоих emp и emp_addr.Это приводит к появлению строки в emp_audit и emp_addr_audit. (INSERT)
Транзакция № 2: Я обновляю вышеупомянутый атрибут emp '.Это приводит к появлению строки UPDATE в emp_audit.
Транзакция № 3: Я обновляю вышеуказанный атрибут emp_addr.Это приводит к появлению строки UPDATE в emp_addr_audit.
Я попробовал следующий 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 будет STILL смог получить мне 3 строки для 3 транзакций, чтобы я мог отфильтровать их по empnum?