Функции и триггеры

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

Функции и триггеры PostgreSQL совместно образуют мощный слой автоматизации на стороне сервера, выполняющий логику непосредственно внутри движка реляционной базы данных — близко к данным. Функция, определённая с помощью CREATE FUNCTION на plpgsql, sql или другом поддерживаемом языке, инкапсулирует многократно используемую бизнес-логику — валидацию, вычисления, журналирование изменений — и может возвращать скаляры, наборы строк или даже таблицы, открывая возможности для глубокой оптимизации запросов через встраивание. Триггер — это механизм, автоматически вызывающий функцию при наступлении указанного DML-события (INSERT, UPDATE, DELETE или TRUNCATE) на таблице: с временно́й привязкой BEFORE или AFTER; при этом PostgreSQL передаёт старые и новые значения строк в функцию триггера через специальные переменные OLD и NEW. Триггеры применяются в PostgreSQL для принудительного применения сложных бизнес-правил, поддержания денормализованных агрегированных столбцов, реализации паттернов мягкого удаления и генерации событий захвата изменений данных, что делает их ключевым элементом продвинутого проектирования реляционных баз данных за рамками простых CRUD-операций.

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

Функции и триггеры переносит логику в БД. 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-файлы.

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

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