Триггеры

Тема дорожной карты · PostgreSQL

Триггер PostgreSQL — объект базы данных, автоматически вызывающий функцию триггера до или после события INSERT, UPDATE, DELETE или TRUNCATE на таблице или представлении, обеспечивающий автоматическое применение сложных бизнес-правил, журналирование изменений и проверки согласованности данных. Триггеры определяются командой CREATE TRIGGER с указанием времени срабатывания (BEFORE, AFTER или INSTEAD OF), инициирующего события, режима срабатывания — один раз на строку (FOR EACH ROW) или один раз на оператор (FOR EACH STATEMENT) — и функции на PL/pgSQL (или другом языке) для выполнения. В триггерах FOR EACH ROW специальные переменные NEW и OLD хранят новую и старую версии строки соответственно, позволяя функции триггера инспектировать, изменять или отклонять изменение. Триггеры PostgreSQL широко применяются для административных задач: обновления временны́х меток updated_at, ведения таблиц аудита, обеспечения ссылочной целостности за рамками внешних ключей и репликации данных в денормализованные агрегирующие таблицы. Тщательный контроль накладных расходов триггеров — в частности, предотвращение каскадных триггеров и избыточной логики на уровне строк в горячих таблицах — важен для настройки производительности PostgreSQL.

Как это работает

Триггеры переносит логику в БД. PL/pgSQL — дефолтный процедурный язык; PL/Python, PL/V8, PL/Perl тоже есть. Функции возвращают скаляр, set-of или table-типы; триггеры срабатывают BEFORE/AFTER на INSERT/UPDATE/DELETE/TRUNCATE per ROW или per STATEMENT. Для чего: валидация данных, держащаяся независимо от приложения, audit trail, computed-колонки (generated columns проще в большинстве случаев), денормализация, синхронизируемая в БД.

Когда применять

Функции — для инвариантов, держащихся независимо от приложения (enforce constraint, нормализация). Триггеры — для audit-логирования или поддержки производных колонок. Избегайте тяжёлой бизнес-логики в stored procedures — Git, тесты, observability для DB-кода хуже чем для app; dev round-trip медленный. Generated columns — для простых производных; дешевле триггеров.

Типичные ошибки

Ловушки Триггеры: цепочки триггеров (один зовёт функцию, та срабатывает триггер, который...); рекурсивные триггеры без base case (взрыв стека); триггеры, читающие извне транзакции (race condition); бизнес-логика наполовину в приложении, наполовину в БД (удачи новым инженерам). Закрепляйте функции в схеме, версионируйте как SQL-файлы.

Связанные понятия

Полезные ресурсы