SEQUENCE и SERIAL

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

Последовательность в PostgreSQL — объект базы данных, генерирующий монотонно возрастающий (или убывающий) ряд целых чисел, используемый преимущественно для формирования уникальных значений первичного ключа в таблицах. Псевдотип SERIAL (и его современный эквивалент GENERATED ALWAYS AS IDENTITY) — это сокращение, автоматически создающее последовательность и связывающее вызов её функции nextval() в качестве значения по умолчанию для столбца; этот паттерн является стандартным для автоинкрементных идентификаторов при администрировании баз данных PostgreSQL. Последовательности — это самостоятельные объекты, управляемые командами CREATE SEQUENCE, ALTER SEQUENCE и DROP SEQUENCE; они могут совместно использоваться несколькими таблицами, иметь настраиваемые начальные значения, шаги, минимальные/максимальные ограничения и кэш (CACHE) для повышения производительности за счёт сокращения числа операций обновления объекта последовательности на каждую строку. Поскольку значения последовательности выделяются вне вызывающей транзакции и никогда не откатываются, пропуски в значениях являются нормальным и ожидаемым поведением PostgreSQL — их не следует расценивать как ошибки. Для потребностей в глобально уникальных идентификаторах функции uuid-ossp или gen_random_uuid() PostgreSQL являются альтернативой столбцам SERIAL на основе последовательностей.

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

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

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

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

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

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