Стандартная практика ведения истории изменения данных таблицы.
Вешаете триггер по операциям UPDATE, INSERT, DELETE перед их выполнением (опция before) на интересуемую таблицу и вставляете данные из атрибутов old.* триггера в таблицу истории.
Таблица истории:
history_id - идент. записи истории
next_history_id - идент. следующей записи истории в пределах одной записи отслеживаемой таблицы (у последней он null)
oper_type - тип операции (UPDATE, INSERT, DELETE - можно числами записать)
old.* - все атрибуты таблицы, значения до выполнения операции.
new.* - все атрибуты таблицы, которые пытались внести операциями UPDATE или INSERT. Этот набор нужен, если вы следите за историей на транзакциях, которые были откатаны назад (неудачные попытки). В этом случае, в триггере нужно указать специальную опцию, чтобы он работал в режиме автономной транзакции.
При внесении новой записи истории, в предыдущей записи по такому же первичному ключу отслеживаемой таблицы нужно добавлять next_history_id от history_id новой записи.
Таким образом в отслеживаемой таблице будет актуальное состояние записи, а в таблице истории - цепочка изменений записей.
По каждому первичному ключу записи отслеживаемой таблицы можно построить цепочку изменений по history_id и next_history_id.
А по next_history_id is null можно быстро получить последнее изменение из этой цепочки.
Естественно, к этим полям нужно добавить индексы.