MySQL игнорирует нулевые значения в уникальных ограничениях?

291

У меня есть столбец электронной почты, который я хочу быть уникальным. Но я также хочу, чтобы он принимал нулевые значения. Может ли моя база данных иметь 2 пустых электронных письма таким образом?

Хьюго Мота
источник
возможный дубликат ограничения уникальности, который допускает пустые значения в MySQL
Пауло Коги - Восстановить Монику

Ответы:

426

Да, MySQL допускает наличие нескольких NULL в столбце с уникальным ограничением.

CREATE TABLE table1 (x INT NULL UNIQUE);
INSERT table1 VALUES (1);
INSERT table1 VALUES (1);   -- Duplicate entry '1' for key 'x'
INSERT table1 VALUES (NULL);
INSERT table1 VALUES (NULL);
SELECT * FROM table1;

Результат:

x
NULL
NULL
1

Это не верно для всех баз данных. Например, SQL Server 2005 и более ранние версии допускают только одно значение NULL в столбце с уникальным ограничением.

Марк Байерс
источник
37
отличный комментарий о том, как это верно в MySQL, но не обязательно в целом.
user2910265
11
По SQLite FAQ , поведение является то же самое в MySQL, PostgreSQL, SQLite, Oracle и Firebird.
Амир Али Акбари
4
Пожалуйста, обновите свой ответ. В SQLServer 2008+ это абсолютно необходимо, вам просто нужно добавить предложение WHERE ... в 2017 году никто не должен быть на более старой версии, чем в 2008 году ... stackoverflow.com/questions/767657/…
Матье Туркотт,
эта маленькая особенность была очень трудна, чтобы найти ответ, который не требует добавления нового столбца в базу данных или обновления MySQL на очень старом приложении. Я действительно искал решение, такое как Postgres, где я мог бы использовать COALESCE, но кажется, что ответ всегда в том, что это не ошибка, а то, как он разработан. WHERE column IS NOT NULLКажется, даже не подведет меня, поскольку он не поддерживается в моей версии MySQL. Кто-нибудь знает, где я могу посмотреть?
newdark-it
1
примечание: это также работает и уникальные индексы, которые имеют больше столбцов. Поэтому, если вы хотите, чтобы столбцы a, b и c были уникальными, вы все равно можете иметь в таблице двойные строки с нулем, b, c
Михай Крэйджа,
112

Из документов :

«Индекс UNIQUE разрешает несколько значений NULL для столбцов, которые могут содержать NULL»

Это относится ко всем двигателям, кроме BDB .

Мэтью Флэшен
источник
3
BDB больше не доступен в текущих версиях mysql (начиная с 5.1.12).
Алим Оздемир
1
Мои тесты, кажется, показывают, что база данных Java Derby v10.13.1.1. аналогично, допускается только один нуль в столбце с уникальным индексом.
chrisinmtown
8

Я не уверен, изначально ли автор просто спрашивал, позволяет ли это дублировать значения, или здесь был подразумеваемый вопрос: «Как разрешить дублирование NULLзначений при использовании UNIQUE?» Или "Как разрешить только одно UNIQUE NULLзначение?"

На вопрос уже дан ответ, да, вы можете иметь повторяющиеся NULLзначения при использовании UNIQUEиндекса.

Так как я наткнулся на этот ответ при поиске «как разрешить одно UNIQUE NULLзначение». Для всех, кто может наткнуться на этот вопрос, делая то же самое, остальная часть моего ответа для вас ...

В MySQL вы не можете иметь одно UNIQUE NULLзначение, однако вы можете иметь одно UNIQUEпустое значение, вставляя в него значение пустой строки.

Предупреждение. Числовые значения и типы, отличные от строки, могут по умолчанию принимать значение 0 или другое значение по умолчанию.

bluegman991
источник
1
Ограничение не имеет ничего общего с индексом. Фактически, вы даже не сможете иметь одну строку со значением NULL, несмотря на то, что другой такой строки нет.
Пиюсн
1
@Pijusn Что вы подразумеваете под "ограничение не имеет ничего общего с индексом?" Что касается вашего второго предложения, я никогда не говорил, что у вас может быть строка со значением NULL, поэтому я заявил в начале поста, что это решение, только если он не настроен на использование нулевых значений.
bluegman991
Я имел в виду, что добавление нового элемента завершается неудачей не из-за UNIQUEограничений, а из-за NOT NULLограничений. Я думаю, что этот ответ не имеет отношения к вопросу, потому что вопрос конкретно о поведении UNIQUEограничения.
Пиюсн
@Pijusn Я получил тебя. Вы правы, я удалил формулировку, предполагающую обратное. Я неправильно прочитал вопрос. Но я полагаю, что ответ все еще может быть полезен для пользователей, которые сталкиваются с этим вопросом, как и я, пытаясь найти способ получить уникальное значение «ничего», но по ошибке допускают нулевую способность.
bluegman991
1
Я нашел этот ответ полезным. Тем не менее, это также ответ здесь . Этот пост был первым результатом моего поиска в Google, хотя этот ответ и связанный вопрос были тем, что я искал.
kingledion
5

Избегайте обнуляемых уникальных ограничений. Вы всегда можете поместить столбец в новую таблицу, сделать его ненулевым и уникальным, а затем заполнить эту таблицу только тогда, когда у вас есть для нее значение. Это гарантирует, что любая зависимость ключа от столбца может быть корректно применена, и позволяет избежать любых проблем, которые могут быть вызваны пустыми значениями.

nvogel
источник
6
Да, но то, что вы предлагаете, это почти то, что MySQL делает за кулисами. Зачем изобретать велосипед, если эта функциональность встроена?
ProfileTwist
2
Потому что это не правильный SQL. Я считаю, что этот совет будет полезен всем, кто хочет (или нуждается) в независимом от базы данных дизайне.
Arsen7
@ Arsen7 Что делать, если у вас есть несколько предприятий - каждый с несколькими клиентами. Вы храните все дела с адресами электронной почты своих клиентов в одном файле. Таким образом, вы не можете сделать email_address уникальным, потому что разные компании могут иметь одного и того же клиента. Таким образом, вы должны составить уникальный индекс business_id и email_address. Можно ли поместить это в новую таблицу - как объяснено?
Герхард Либенберг
4
У меня есть случай, когда столбец «электронной почты» должен быть уникальным ИЛИ пустым. Мне бы пришлось создать новую таблицу с одним столбцом «электронная почта», если бы я следовал вашему совету. Полагаться на это специфическое поведение Mysql намного проще и результат тот же. Клиенту все равно, сохраню я электронную почту в новой таблице или нет. Кроме того, независимый от базы данных дизайн часто переоценивают. Для многих проектов вы не можете и, вероятно, не просто переключитесь с одной БД на другую так легко.
conradkleinespel
1
@djmj, конечно, но функциональные зависимости важны для большинства людей, и версия с уникальным ограничением обнуляемая не обеспечивает тех же зависимостей, что и версия BCNF. То, какой вариант более или менее практичен, может зависеть от того, какие зависимости важны для вас. Вот почему стоит подумать о создании новой таблицы.
nvogel