ARRAY и ENUM
Тема дорожной карты · PostgreSQL
PostgreSQL предоставляет полноценную поддержку массивов и перечисляемых типов — двух мощных инструментов моделирования данных, отличающих его от многих других реляционных СУБД. Столбец-массив, объявляемый с суффиксом типа, например INTEGER[] или TEXT[], позволяет хранить в одной строке несколько значений без необходимости создавать отдельную связующую таблицу; PostgreSQL предоставляет операторы ANY, ALL и @> для эффективных запросов и индексирования массивов. Тип ENUM, создаваемый командой CREATE TYPE mood AS ENUM ('happy', 'sad', 'neutral'), закрепляет на уровне базы данных фиксированный набор допустимых строковых значений, снижая необходимость в валидации на стороне приложения и улучшая оптимизацию запросов за счёт более компактного хранения и семантики сравнения. Оба типа — массивы и перечисления — органично интегрируются с инфраструктурой индексирования PostgreSQL, и их понимание необходимо для продвинутого проектирования типов данных в любом приложении, использующем PostgreSQL в качестве реляционной базы данных.
Как это работает
ARRAY и ENUM покрывает numeric (int, bigint, numeric, real, double), character (text, varchar, char — берите text, кроме реального лимита), date/time (timestamp, timestamptz — всегда tz-вариант), boolean, JSONB (запросимый JSON с GIN-индексами), массивы (int[], text[]), ranges (int4range, tsrange), UUID, network (inet, cidr), геометрические, кастомные через DOMAIN или CREATE TYPE. Postgres необычно богат — используйте типы, а не перегружайте text/JSONB.
Когда применять
Всегда timestamptz (timestamp with time zone) для меток времени — Postgres хранит UTC + конвертирует на показ. numeric(10,2) для денег, никогда real/float (округление). uuid для ID, видимых клиентам (нет утечки объёма vs integer); bigint — для внутренних high-volume последовательностей. JSONB (не JSON) — бинарный, индексируется, быстрее. Enum использовать аккуратно (тяжело мигрировать); lookup-таблица часто яснее.
Типичные ошибки
Ловушки ARRAY и ENUM: timestamp (без tz) и тихое хранение локального (DST-ужас); varchar(255) "потому что MySQL" (в Postgres нет perf-выгоды — используйте text); JSON вместо JSONB (текст, медленней, без индексов); float для денег (копейка тут, копейка там — за годы). Прочтите справочник типов — окупается лучшими решениями по схеме.