Что такое constraints (ограничения) в SQL и какие бывают?
Делаю первый проект с базой данных, постоянно встречаю слово constraints в туториалах, но не до конца понимаю, зачем они нужны. Какие вообще бывают ограничения и для чего каждое? Хотелось бы увидеть пример CREATE TABLE, где всё это используется вместе.
2 ответа
Constraints (ограничения) — это правила, которые СУБД проверяет автоматически при вставке и изменении данных. Их смысл в том, чтобы база сама не дала записать мусор, даже если в коде приложения закралась ошибка. Это последняя линия обороны целостности данных.
Основные виды:
- NOT NULL — поле обязано иметь значение, нельзя оставить пустым.
- UNIQUE — значения в столбце не должны повторяться (например, email).
- PRIMARY KEY — уникальный идентификатор строки. По сути
UNIQUE + NOT NULL, и в таблице он один. - FOREIGN KEY — значение должно ссылаться на существующую строку в другой таблице. Защищает от «висячих» ссылок.
- CHECK — произвольное условие, например
price > 0. - DEFAULT — не совсем ограничение, но рядом: значение по умолчанию, если его не передали.
Пример, где всё вместе:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
age INT CHECK (age >= 0 AND age < 150),
role VARCHAR(20) NOT NULL DEFAULT 'user',
city_id INT REFERENCES cities(id)
);
Что здесь происходит:
id— первичный ключ, автоинкремент (SERIALв PostgreSQL; в MySQL этоINT AUTO_INCREMENT).emailне может быть пустым и не может повторяться.ageпроверяется условием CHECK — отрицательный возраст не пройдёт.roleпо умолчанию'user', если значение не указали.city_id— внешний ключ на таблицуcities.
Предупреждение: добавлять ограничение к уже заполненной таблице (ALTER TABLE ... ADD CONSTRAINT) можно только если существующие данные ему не противоречат, иначе СУБД отклонит операцию. Сначала почистите данные, потом вешайте ограничение.
Маленькое, но важное дополнение про FOREIGN KEY: продумайте поведение при удалении родительской строки. По умолчанию база не даст удалить город, на который ссылаются пользователи. Часто это не то, что нужно:
city_id INT REFERENCES cities(id) ON DELETE SET NULL
-- или ON DELETE CASCADE — удалит и зависимые строки
CASCADE удобен, но опасен: удалив одну строку, можно случайно снести половину связанных данных. Включайте его осознанно.