Механизм аудита (лог или история изменений) реализуется для отслеживания всех изменений данных и обеспечения прозрачности. Есть несколько основных подходов:
Аудитные триггеры (Audit Triggers): Специальные AFTER/BEFORE INSERT/UPDATE/DELETE триггеры, которые сохраняют старое и/или новое состояние строки в отдельную таблицу аудита. Преимущество — прозрачность для приложения; недостаток — возможное замедление DML-операций.
Изоляция истории в отдельной таблице (History Table): Применяется версияция записей — при изменении "старую" строку копируют в history-таблицу с отметкой времени. Основная таблица содержит только актуальные данные.
Встроенные механизмы (Change Data Capture, Temporal Tables): Например, в SQL Server можно включить SYSTEM_VERSIONED TEMPORAL TABLE, и СУБД будет автоматически хранить историю изменений.
CREATE TABLE user_audit ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT, action VARCHAR(10), old_value TEXT, new_value TEXT, changed_at DATETIME ); DELIMITER // CREATE TRIGGER audit_user_update AFTER UPDATE ON users FOR EACH ROW BEGIN INSERT INTO user_audit (user_id, action, old_value, new_value, changed_at) VALUES (OLD.id, 'UPDATE', OLD.name, NEW.name, NOW()); END// DELIMITER ;
Вопрос: Всегда ли достаточно иметь audit-trigger только на UPDATE, если требуется полный протокол истории изменений?
Ответ: Нет. Полную историю можно получить только комбинируя триггеры на все типы операций: INSERT (логировать новые строки), UPDATE (логировать изменения) и DELETE (логировать удалённые записи).
-- Нужно создать 3 отдельных триггера на каждую операцию, иначе будут "дыры" в истории.
История 1: Компания использовала только UPDATE-триггер для аудита и в течение года не замечала, что удалённые записи никак не фиксируются. В итоге при разборе инцидента не смогли выяснить, когда была удалена важная учетная запись пользователя.
История 2: Проект хранил старое и новое значения изменений в одном текстовом поле в виде сериализованного JSON, что сильно усложнило анализ — потребовались сложные парсеры и отдельная реплика БД для отчётности.
История 3: В БД с высокой нагрузкой разработчики внедрили аудит через триггеры, не учитывая рост объема lоg-таблицы. Со временем таблица истории превысила базовую таблицу в 50 раз, что привело к переполнению хранилища и сбоям во всём проекте.