Хм... Имея в руках только IBConsole я когда-то сделал примерно так как предлогает IBExpert :)
create table LOG_OPERATION
( // таблица в которой каждая запись идентифицируется с одной операцией над одной записью в журналируемой таблице
OPERATIONKEY INTEGER not null, // PK
OPERATIONBLOCKKEY INTEGER not null, // FK на вышестоящюю таблицу
OPERATIONTYPE INTEGER not null, // тип операции
TABLENAME VARCHAR(31) not null, // имя таблицы
PKVALUE INTEGER not null // значение первичного ключа для записи в TABLENAME
);
create table LOG_UPD
( // таблица в которой каждая запись идентифицируется с изменением одного поля
UPDKEY INTEGER not null, // PK
OPERATIONKEY INTEGER not null, // FK на LOG_OPERATION
FIELDNAME VARCHAR(31) not null, // имя поля которое менялось
OLDVAL VARCHAR(255) // старое значение
) |
Да, не скажу, что такой лог очень удобно выводить в грид, но зато он не избыточен в плане занимаемого места как в случае с OLD_VALUE и NEW_VALUE (кстати с ними у меня было сделано в самой первой версии журнала :)) Имея цепочку значений начиная с самого старого (самое новое имеется в поле саой журналируемой таблицы, по этому его незачем хранить в журнале) можем проследить всю историю жизни записи. Гы, вспомнилось что так работает сегмент отката :)
Поддерка лога осуществляется триггерами, триггеры автоматически перегенеряются на основе метаданных, все цветет и пахнет, жизнь прекрасна.
Единственное условие которое сия система требует - это сурогатный ПК на все журналируемые таблицы и этот ключ не должен менятся во время всего цикла жизни записи. Но я не думаю, что это такая уж неприятнось :)
А с блобами... ну незнаю, думаю для них можно завести еще одну таблицу аля LOG_UPD.