Какие ограничения (constraints) бывают в PostgreSQL
Что проверяют
Умеете ли вы переводить бизнес-правила в требования к модели данных. Аналитику не обязательно помнить синтаксис наизусть, но нужно понимать, какое правило база гарантирует сама, а какое останется на совести кода. Следом часто просят разобрать правило из предметной области: где и чем его закрепить.
Как отвечать
Свяжите каждый вид ограничения с тем, как он звучит в требованиях:
- NOT NULL: «поле обязательно». Обязательность в базе и обязательность на форме это разные вещи;
- CHECK: правило на одну строку, например «цена не меньше нуля» или «дата окончания позже даты начала». Заглянуть в другую таблицу CHECK не может;
- UNIQUE: «email не повторяется». Проговорите, как быть с пустыми значениями: по умолчанию несколько
NULLдублями не считаются; - PRIMARY KEY: идентификатор строки, уникальный и обязательный;
- FOREIGN KEY: «заказ принадлежит существующему клиенту». Сюда же относится решение, что делать при удалении клиента: запретить (
RESTRICT), удалить заказы (CASCADE) или обнулить ссылку (SET NULL). Это бизнес-вопрос, и задать его должен аналитик; - EXCLUDE: запрет пересечений, например «переговорку нельзя забронировать на пересекающееся время»:
EXCLUDE USING gist (room_id WITH =, period WITH &&).
Покажите, что ограничения полезны и в самом анализе. Перед миграцией или интеграцией вы проверяете запросами, выполнится ли будущее правило на текущих данных: ищете дубли через GROUP BY ... HAVING count(*) > 1 и строки-сироты через LEFT JOIN ... WHERE ... IS NULL.
Где спотыкаются
Пишут в требованиях «уникальный» и не уточняют границы: глобально, внутри компании или только среди активных записей. Последний случай закрывается частичным уникальным индексом, а не простым UNIQUE.
Приводят исключающее ограничение только по room_id WITH =. Оно запретит комнате иметь больше одной брони вообще, смысл появляется, когда в выражение добавлен интервал с оператором &&.
Считают, что правило, проверенное на форме, соблюдается в базе. Данные приходят ещё через импорт, API и ручные правки, поэтому критичное правило лучше закрепить ограничением.