← Назад к вопросам
Может ли unique key иметь значение null?
1.0 Junior🔥 221 комментариев
#Базы данных и SQL
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Может ли unique key иметь значение NULL?
Да, может! В большинстве СУБД (PostgreSQL, MySQL, SQL Server, Oracle, SQLite) UNIQUE constraint разрешает несколько NULL значений в одном столбце.
Почему NULL обходит UNIQUE?
В SQL стандарте NULL != NULL. Это логическое правило:
SELECT NULL = NULL; -- Результат: NULL (не true!)
SELECT NULL IS NULL; -- Результат: true
Поэтому UNIQUE constraint работает так: "если значение NULL, пропусти проверку уникальности".
Пример проблемы
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE,
phone VARCHAR(20) UNIQUE
);
-- Оба работают!
INSERT INTO users (email, phone) VALUES ('john@test.com', NULL);
INSERT INTO users (email, phone) VALUES ('jane@test.com', NULL);
-- Теперь в phone две NULL! Нарушена уникальность!
Решение 1: NOT NULL
CREATE TABLE users (
email VARCHAR(255) UNIQUE NOT NULL,
phone VARCHAR(20) UNIQUE NOT NULL
);
-- Теперь NULL невозможен
Решение 2: UNIQUE INDEX с WHERE (лучше)
-- PostgreSQL, MySQL 8.0+, SQL Server
CREATE UNIQUE INDEX idx_phone ON users(phone)
WHERE phone IS NOT NULL;
Теперь:
- phone может быть NULL несколько раз (не учитывается в индексе)
- Если phone не NULL, он уникален
Решение 3: CHECK constraint
CREATE TABLE users (
phone VARCHAR(20) UNIQUE,
CHECK (phone IS NOT NULL)
);
Best Practices
- Если столбец должен быть уникальным → добавь NOT NULL
- Если столбец опционален → не используй UNIQUE
- Если нужна условная уникальность → используй UNIQUE INDEX с WHERE
Реальный пример правильного дизайна
CREATE TABLE users (
id BIGINT PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL, -- Обязателен и уникален
phone VARCHAR(20), -- Опционален
social_id VARCHAR(100) -- Опционален
);
CREATE UNIQUE INDEX idx_phone ON users(phone)
WHERE phone IS NOT NULL;
CREATE UNIQUE INDEX idx_social ON users(social_id)
WHERE social_id IS NOT NULL;
Вывод
UNIQUE constraint позволяет NULL из-за логики SQL (NULL != NULL). Это часто ошибка дизайна. Решение: используй NOT NULL для обязательных уникальных полей или UNIQUE INDEX с WHERE для опциональных.