← Назад к вопросам

Будет ли работать Foreign Key одной таблицы относящийся к Unique Key другой таблицы, если Unique Key состоит из 2 колонок и одна из них имеет значение NULL?

3.0 Senior🔥 101 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Foreign Key с Unique Key, содержащим NULL

Это отличный вопрос о тонкостях реляционных баз данных. Ответ: Да, Foreign Key будет работать, но с важными оговорками.

Поведение с NULL в UNIQUE KEY

В SQL существует особенность: NULL считается уникальным значением. То есть, если у вас есть UNIQUE KEY (col1, col2) и col1 или col2 содержит NULL, это не нарушает ограничение уникальности.

-- Таблица с UNIQUE KEY из двух колонок
CREATE TABLE Parent (
    id INT PRIMARY KEY,
    code VARCHAR(50),
    region VARCHAR(50),
    UNIQUE KEY uk_code_region (code, region)
);

-- Эти строки все допустимы (NULL != NULL)
INSERT INTO Parent VALUES (1, A, US);
INSERT INTO Parent VALUES (2, A, NULL);  -- OK
INSERT INTO Parent VALUES (3, NULL, US); -- OK
INSERT INTO Parent VALUES (4, NULL, NULL); -- OK

Foreign Key, ссылающийся на UNIQUE KEY с NULL

Да, Foreign Key может ссылаться на Unique Key (не обязательно на Primary Key). Но при наличии NULL возникают интересные сценарии:

-- Таблица-дочка со Foreign Key
CREATE TABLE Child (
    id INT PRIMARY KEY,
    parent_code VARCHAR(50),
    parent_region VARCHAR(50),
    FOREIGN KEY fk_parent (parent_code, parent_region) 
        REFERENCES Parent(code, region)
);

-- Какие строки можно вставить в Child?
INSERT INTO Child VALUES (1, A, US);      -- OK (ссылается на parent id=1)
INSERT INTO Child VALUES (2, A, NULL);      -- ??
INSERT INTO Child VALUES (3, NULL, US);     -- ??
INSERT INTO Child VALUES (4, NULL, NULL);     -- ??

Правило NULL в Foreign Key

В SQL стандарте и большинстве СУБД (PostgreSQL, MySQL, Oracle):

Eсли ANY колонка в Foreign Key содержит NULL, то ограничение Foreign Key НЕ проверяется. Это связано с тем, что NULL означает "неизвестное значение", и базе данных непонятно, как проверить ограничение.

// Из кода Java это выглядит так:
if (parentCode != null && parentRegion != null) {
    // Проверяем Foreign Key
    validateForeignKeyExists(parentCode, parentRegion);
} else {
    // NULL пропускается (как правило)
}

Практический пример (PostgreSQL)

-- Гарантированно работает
INSERT INTO Child VALUES (1, A, US);      -- ✓ Проверка FK пройдёт

-- NULL пропускают проверку FK
INSERT INTO Child VALUES (2, A, NULL);      -- ✓ Вставится (NULL не проверяется)
INSERT INTO Child VALUES (3, NULL, NULL);     -- ✓ Вставится

-- Несуществующий родитель
INSERT INTO Child VALUES (4, X, Y);       -- ✗ Ошибка (FK нарушено)

Итоговый ответ

Foreign Key будет работать, но:

  1. Если обе колонки заполнены — проверяется наличие соответствующей строки в Parent
  2. Если хотя бы одна колонка NULL — проверка Foreign Key пропускается
  3. NULL не нарушает уникальность UNIQUE KEY, поэтому можно иметь несколько строк с NULL

Это нужно учитывать при проектировании базы данных. Если вам нужна строгая ссылочная целостность, избегайте NULL в Foreign Key колонках.

Будет ли работать Foreign Key одной таблицы относящийся к Unique Key другой таблицы, если Unique Key состоит из 2 колонок и одна из них имеет значение NULL? | PrepBro