Может ли unique key иметь значение null

Ответ

Да, уникальный ключ (unique key) в MySQL может содержать значение NULL. Однако есть нюанс: уникальный ключ допускает несколько записей с NULL, так как NULL не считается равным другому NULL (сравнение NULL = NULL возвращает NULL, а не true).

Пример:

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    email VARCHAR(255) UNIQUE
);

INSERT INTO users (email) VALUES (NULL); -- OK
INSERT INTO users (email) VALUES (NULL); -- OK, так как NULL != NULL

Если нужно запретить дублирование NULL, можно использовать NOT NULL в сочетании с UNIQUE:

ALTER TABLE users MODIFY email VARCHAR(255) NOT NULL UNIQUE;

В других СУБД (PostgreSQL, SQLite) поведение может отличаться.

Ответ 18+ 🔞

А, ну это классика, ёпта! Про уникальные ключи и NULL — тут история, как в том анекдоте про слепого и глухого. Слушай, разбираем по косточкам.

Вот смотри, в MySQL уникальный ключ — он как тот самый сосед, который вроде бы строгий, но на одно конкретное безобразие закрывает глаза. Значение NULL он пропускает, и не просто так, а с размахом: можешь хоть десять записей с NULL натыкать — и всё будет окей. Потому что, блядь, NULL — это не значение, а состояние неизвестности, хуй с горы. И сравнение NULL = NULL возвращает не true, а тоже NULL, то есть «хз, чё тут говорить». Поэтому дубликатами NULL не считаются, хоть тресни.

Вот тебе живой пример, смотри:

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    email VARCHAR(255) UNIQUE
);

INSERT INTO users (email) VALUES (NULL); -- Ну окей, прошло
INSERT INTO users (email) VALUES (NULL); -- И это окей, потому что NULL != NULL

Представляешь? Два NULL — и тишина, никаких ошибок. Уникальность не ругается, будто так и надо. Но если воткнешь два одинаковых реальных email — тут же получишь по шапке, сразу Duplicate entry, ядрёна вошь!

А теперь, если тебе это поведение не нравится, и ты хочешь, чтобы NULL был один, как пердящий смерд в лифте, то делаем просто: добавляем NOT NULL. Тогда поле сразу становится строгим, как училка в школе: и пустым быть не может, и дубликаты не прокатят.

ALTER TABLE users MODIFY email VARCHAR(255) NOT NULL UNIQUE;

Вот и всё, красота. Но, чувак, держи ухо востро: в других базах данных, типа PostgreSQL или SQLite, правила могут быть другими. Там, блядь, иногда NULL считается уникальным, и дубликаты уже не прокатят. Так что, когда пересаживаешься на другую СУБД — лучше проверь, а то будет тебе хиросима на ровном месте.