awesome-everything EN
↑ Обратно к восхождению

Базы данных

Ограничения, ключи и типы данных Postgres

Суть Пять видов ограничений в деталях, суррогатные vs натуральные ключи, разрыв SQL с реляционной алгеброй и почему выбор минимального типа Postgres — тоже ограничение.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 16 min

Команда хранит деньги в REAL. После года накопленных транзакций обнаруживаются расхождения на уровне центов, которые невозможно объяснить. Тип и был ошибкой — арифметика float теряет точность. Исправление — изменение схемы, затрагивающее каждую строку.

Реляционная модель Кодда vs SQL

Статья Эдгара Кодда 1970 года формализовала отношения как наборы кортежей из типизированных доменов и определила замкнутую алгебру операций (выборка, проекция, соединение, объединение, пересечение, разность) — замкнутую потому, что каждая операция принимает отношения на вход и возвращает отношение на выход. SQL — нестрогая реализация этой алгебры; он добавляет NULL (что Кодду не нравилось), ORDER (строки концептуально неупорядочены) и дублирующиеся строки (в отношениях дублей нет). Знание этого разрыва объясняет шероховатости:

  • NULL = NULL — это NULL, не true: трёхзначная логика.
  • ORDER BY обязателен для гарантии порядка строк — без него движок вернёт любой порядок.
  • DISTINCT существует потому, что движок должен хранить дубли, пока вы не попросите иначе.

Воспринимайте разрыв как «SQL = реляционная алгебра плюс практические компромиссы» — и неожиданности перестанут удивлять.

Пять видов ограничений

ОграничениеЧто принудительно соблюдаетКлючевая деталь
PRIMARY KEYУникальный ненулевой идентификатор строкиОдин на таблицу; неявно создаёт уникальный B-tree индекс
UNIQUEНет дублей в наборе колонокНесколько NULL допустимы (стандарт SQL); UNIQUE NULLS NOT DISTINCT (SQL:2023 / Postgres 15+) запрещает это
NOT NULLКолонка всегда имеет значениеДля каждой колонки; первый рубеж качества данных
FOREIGN KEYКолонка ссылается на существующий PK/UNIQUE другой таблицыПараметры ON DELETE / ON UPDATE: NO ACTION, RESTRICT, CASCADE, SET NULL, SET DEFAULT
CHECKПроизвольное булево выражение на каждой строке при записиCHECK (amount >= 0), CHECK (status IN (‘open’,‘closed’)) — может ссылаться на другие колонки той же строки

Суррогатные vs натуральные ключи

Натуральный ключ — данные, уже существующие в бизнес-домене (email пользователя, SKU продукта, номер заказа). Суррогатный ключ — генерируемый базой, непрозрачный, значимый только внутри базы (BIGSERIAL, UUID).

Продакшн-дефолт в 2026: суррогатный ключ как primary key плюс ограничение UNIQUE NOT NULL на бизнес-натуральный ключ. Почему: натуральные ключи меняются (клиент меняет email), а изменение primary key каскадирует через каждый ссылающийся foreign key — операционно дорогостояще и часто невозможно при масштабе. Суррогатные ключи никогда не меняются.

Исключение: чистые join-таблицы (favourites: user_id, item_id) часто используют композит из foreign keys как PK — сама связь и есть идентичность, суррогат не нужен.

UUID vs BIGSERIAL. UUID глобально уникальны (хороши для распределённых вставок, мультирегионов, offline-first клиентов), но больше (16 байт против 8) и хуже для локальности индекса (случайные UUIDv4 фрагментируют B-tree). UUIDv7 (упорядоченный по времени, RFC 9562) решает проблему локальности и является современным дефолтом там, где нужен UUID. BIGSERIAL меньше, последователен и cache-friendly — выбирайте его, когда глобально уникальные ID не нужны.

Типы данных Postgres: выбирайте минимально необходимый

У Postgres богатейшая система типов среди всех популярных баз данных. Тип — первый рубеж ограничения: правильно типизированная колонка отсекает 80% плохих данных до того, как сработает любое CHECK ограничение.

КатегорияПродакшн-дефолтыИзбегать
ЦелыеBIGINT (8B) для ID; INTEGER (4B) при ограниченном домене < ~2BSMALLINT без уверенности, что < 32 767
СтрокиTEXT (без ограничения длины, без padding)CHAR(n) — padding до длины, сюрпризы с пробелами; VARCHAR(n) добавляет проверку, но не даёт выигрыша в хранении
ДеньгиNUMERIC(p,s) или BIGINT cents — точная арифметикаREAL или DOUBLE PRECISION — IEEE 754 теряет центы
ВремяTIMESTAMPTZ (хранит UTC, отображает в timezone сессии)TIMESTAMP (без зоны) — ловушка; DATE для дат
IDUUID нативный тип (16 байт)UUID как TEXT — тратит байты, теряет принудительный тип
БулевыBOOLEANSMALLINT или TEXT для булевых — семантически неверно
ПолуструктурированныеJSONB (бинарный, индексируемый)JSON (только текст, не индексируемый)
Числа по ключам и типам
Статья Кодда
1970
BIGSERIAL на запись в индексе
8 байт
UUID на запись в индексе
16 байт
UUIDv7 vs UUIDv4 локальность индекса
упорядоченный vs случайный
Overhead проверки FK-ограничения
~5-50 мкс / строка
Размер GIN-индекса JSONB vs B-tree
~5-20x больше
Типичный overhead хранения колонки
~1-4 байта / колонка
Размер записи составного PK в индексе
~24-48 байт

Спроектируйте минимальную e-commerce схему (users, products, orders)

1/3
Викторина

Команда хранит деньги в REAL и обнаруживает расхождения на уровне центов после года транзакций. Исправление?

Викторина

Какой самый весомый аргумент в пользу суррогатного primary key (BIGSERIAL или UUID) перед натуральным (email)?

Вспомните перед уходом
  1. 01
    Почему NULL = NULL не TRUE в SQL и чему это равно?
  2. 02
    Назовите параметры ON DELETE для foreign key и когда каждый используется.
  3. 03
    Что является продакшн-дефолтом для хранения валюты в Postgres и почему не REAL?
Итог

SQL — это реляционная алгебра плюс практические компромиссы: NULL, порядок и дубли. Пять видов ограничений (PRIMARY KEY, FOREIGN KEY, NOT NULL, UNIQUE, CHECK) кодируют бизнес-правила, которые движок не нарушает. Продакшн-дефолт для primary keys — суррогатный (BIGSERIAL или UUIDv7) плюс UNIQUE NOT NULL на бизнес-натуральный ключ: натуральные ключи меняются, суррогатные — никогда. Типы Postgres — первый рубеж ограничений: NUMERIC для денег, TIMESTAMPTZ для временных меток, TEXT для строк, JSONB (не JSON) для полуструктурированных данных. Урок 3 разбирает нормализацию — дисциплину удаления избыточности из схемы.

Связанные уроки
встречается в164
Продолжить восхождение ↑Нормальные формы, денормализация и почему схемы «прилипают»
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.