ПрограммированиеFullstack разработчик

Что такое констрейнты (constraints) в SQL, какие бывают типы ограничений, и как они помогают избежать ошибок в прикладной логике? Приведите примеры использования.

Проходите собеседования с ИИ помощником Hintsage

Ответ

Констрейнты (constraints) — это ограничения целостности, накладываемые на столбцы или таблицы для автоматического контроля допустимости значений. Они позволяют:

  • Защитить данные от неправильного ввода;
  • Снять часть прикладной логики в базу (надежнее и быстрее);
  • Автоматически проверять условия при вставке, апдейте или удалении.

Виды основных констрейнтов:

  • PRIMARY KEY — уникальный идентификатор, запрещает дублирование и NULL.
  • UNIQUE — запрещает дублирование значений в одном столбце.
  • FOREIGN KEY — ссылочная целостность, связь с другой таблицей.
  • CHECK — проверка произвольного выражения.
  • NOT NULL — запрет на NULL значений в столбце.

Пример:

CREATE TABLE orders ( id SERIAL PRIMARY KEY, user_id INT REFERENCES users(id), -- foreign key price DECIMAL(10,2) CHECK (price > 0), created_at TIMESTAMP NOT NULL );

Вопрос с подвохом

"Является ли уникальный ключ (UNIQUE) автоматически NULL-SAFE, исключая любое количество NULL-значений в столбце?"

На самом деле, в большинстве СУБД (например, PostgreSQL, MySQL) ограничение UNIQUE допускает несколько строк со значением NULL, так как NULL рассматривается как "неизвестное". Это часто приводит к незаметному дублированию пустых значений.

Пример:
CREATE TABLE test ( id INT PRIMARY KEY, code VARCHAR(10) UNIQUE ); INSERT INTO test (id, code) VALUES (1, NULL), (2, NULL); -- пройдет

Примеры реальных ошибок из-за незнания тонкостей темы


История

Приложение допускало регистрацию по email, столбец был UNIQUE, но НЕ NOT NULL — в таблице оказалось с десяток пользователей с NULL-email, что вызвало проблемы при интеграции с внешними сервисами.


История

В системе заказа билетов забыли добавить FOREIGN KEY к таблице payments — в результате появились платежи, не связанные ни с одним заказом, что мешало проводить возврат пользователям.


История

CHECK-констрейнт для скидки: discount > 0. Была забыта граничная ситуация для 0. Итог: система принимала только скидки больше 0, а отсутствие скидки (0) ломало бизнес-логику.