Может ли столбец в составе составного уникального ключа (Composite Unique Key) допускать значение NULL?

«Может ли столбец в составе составного уникального ключа (Composite Unique Key) допускать значение NULL?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, может. Однако поведение при наличии NULL-значений зависит от конкретной СУБД.

Основные варианты поведения:

СУБД Поведение для UNIQUE-ограничения с NULL
MySQL, PostgreSQL, SQLite NULL != NULL. Несколько строк с NULL в одном и том же столбце составного ключа не нарушают уникальность. Каждый NULL считается уникальным.
Oracle, SQL Server NULL = NULL (в контексте ограничения). Допускается только одна строка с конкретной комбинацией NULL и не-NULL значений. Вторая строка с таким же NULL нарушит уникальность.

Пример для MySQL/PostgreSQL:

CREATE TABLE Users (
    id INT PRIMARY KEY,
    email VARCHAR(255),
    phone VARCHAR(255),
    UNIQUE KEY unique_contact (email, phone) -- Составной уникальный ключ
);

-- Эти вставки УСПЕШНЫ (не нарушают уникальность):
INSERT INTO Users VALUES (1, 'alice@example.com', NULL);
INSERT INTO Users VALUES (2, 'alice@example.com', NULL); -- Допустимо в MySQL/PostgreSQL
INSERT INTO Users VALUES (3, NULL, '+123456789');
INSERT INTO Users VALUES (4, NULL, '+123456789'); -- Также допустимо

Практический совет: Если требуется трактовать все NULL-значения как одинаковые и запрещать их дублирование, используйте:

  • Ограничение NOT NULL на столбцы.
  • Генерируемые значения-заглушки.
  • Триггеры для проверки бизнес-логики.