CREATE FUNCTION

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

CREATE FUNCTION — команда PostgreSQL для определения серверных функций, инкапсулирующих многократно используемую логику непосредственно внутри реляционной базы данных, что сокращает количество сетевых обращений и открывает возможности для продвинутой оптимизации запросов через встраивание и проталкивание вычислений. Функция PostgreSQL объявляется с именем, типизированными параметрами, возвращаемым типом, процедурным языком (обычно plpgsql, sql или plpython3u) и телом — например: CREATE FUNCTION get_balance(uid BIGINT) RETURNS NUMERIC AS $$ SELECT balance FROM accounts WHERE id = uid; $$ LANGUAGE sql STABLE. Категории изменчивости VOLATILE, STABLE и IMMUTABLE сообщают планировщику PostgreSQL, насколько агрессивно он может кэшировать или встраивать результаты функции, непосредственно влияя на планы выполнения, видимые в EXPLAIN ANALYZE. Функции отличаются от процедур (CREATE PROCEDURE) тем, что всегда возвращают значение и могут использоваться внутри выражений SELECT, тогда как процедуры вызываются через CALL и поддерживают управление транзакциями внутри своего тела.

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

CREATE FUNCTION переносит логику в БД. 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 — для простых производных; дешевле триггеров.

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

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

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

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