Чи ігнорує MySQL нульові значення на унікальних обмеженнях?


289

У мене є стовпець електронної пошти, який хочу бути унікальним. Але я також хочу, щоб він приймав нульові значення. Чи може така база даних мати 2 нульові електронні листи?


Відповіді:


423

Так, 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, але не обов’язково в цілому.
користувач2910265

11
За SQLite FAQ , поведінка є те ж саме в MySQL, PostgreSQL, SQLite, Oracle і Firebird.
Амір Алі Акбарі

4
Будь ласка, оновіть свою відповідь. SQLServer 2008+ абсолютно дозволяє це, ви просто повинні додати пункт WHERE ... у 2017 році ніхто не повинен бути на старій версії, ніж 2008 р. ... stackoverflow.com/questions/767657/…
Mathieu Turcotte

ця маленька функція була дуже складно знайти відповідь, що не вимагає додавання нового стовпця до бази даних або оновлення MySQL на дуже старий додаток. Я дійсно шукав таке рішення, як Postgres, де я можу використовувати COALESCE, але, здається, відповідь - це не помилка, як це розроблено. Навіть, WHERE column IS NOT NULLздається, не виходить з ладу, оскільки це не підтримується в моїй версії MySQL. Хто-небудь знає, де я міг шукати?
newdark-це

1
зауважте: це також працює також унікальними індексами, які мають більше стовпців. Тож якщо ви хочете, щоб стовпці a, b і c були унікальними, ви все одно можете мати в таблиці подвійні рядки з null, b, c
Mihai Crăiță

111

З документів :

"індекс UNIQUE дозволяє декілька значень NULL для стовпців, які можуть містити NULL"

Це стосується всіх двигунів, крім BDB .


3
BDB більше не доступний у поточних версіях mysql (починаючи з 5.1.12).
Алім Оздемір

1
Моє тестування, схоже, показує, що база даних Дербі Java v10.13.1.1. аналогічно дозволяє лише один нуль у стовпці з унікальним індексом.
chrisinmtown

7

Я не впевнений, що автор спочатку просто запитував, чи дозволяє це повторювати значення чи ні тут мається на увазі запитання: "Як дозволити повторювані NULLзначення під час використання UNIQUE?" Або "Як дозволити лише одне UNIQUE NULLзначення?"

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

Оскільки я натрапив на цю відповідь, шукаючи "як дозволити одне UNIQUE NULLзначення". Для всіх, хто може спіткнутися з цим питанням, роблячи те саме, решта моєї відповіді - для вас ...

У MySQL не може бути одного UNIQUE NULLзначення, однак ви можете мати одне UNIQUEпорожнє значення, вставивши зі значенням порожнього рядка.

Попередження: Числові та інші типи, крім рядка, можуть мати значення 0 або інше значення за замовчуванням.


1
Обмеження не має нічого спільного з індексом. Насправді ви навіть не зможете мати один рядок зі значенням NULL, незважаючи на те, що іншого такого рядка немає.
Піджун

1
@Pijusn Що ви маєте на увазі під "обмеженням нічого спільного з індексом?" Також щодо вашого другого речення я ніколи не казав, що у вас може бути рядок зі значенням NULL, тому я на початку публікації заявив, що це рішення, лише якщо він не налаштований на використання нульових значень.
bluegman991

Я мав на увазі те, що додавати новий елемент не вдається через UNIQUEобмеження, а через NOT NULLобмеження. Я вважаю, що ця відповідь не має значення для питання, оскільки питання стосується конкретно поведінки UNIQUEобмеження.
Pijusn

@Pijusn Я отримав тебе. Ви маєте рацію, я вилучив формулювання, пропонуючи інакше. Я неправильно прочитав питання. Але я вважаю, що відповідь все-таки може бути корисною для користувачів, які натрапляють на це питання, як і я, намагаючись знайти спосіб отримати унікальне значення "нічого", але помилково дозволяють домогтися.
bluegman991

1
Я вважав цю відповідь корисною. Тим НЕ менше, він також відповів тут . Ця публікація стала першим результатом мого пошуку в Google, хоча я шукав цю відповідь і пов'язане питання.
королевиця

5

Уникайте унікальних обмежень. Ви завжди можете помістити стовпець у нову таблицю, зробити її ненульовою та унікальною, а потім заповнити цю таблицю лише тоді, коли для неї є значення. Це гарантує, що будь-яку ключову залежність від стовпчика можна правильно застосувати та уникне будь-яких проблем, які можуть бути викликані нулями.


6
Так, але те, що ви пропонуєте, - це майже саме те, що mysql вже робить за лаштунками. Навіщо переосмислювати колесо, якщо вбудована ця функціональність?
ProfileTwist

2
Тому що це недійсний SQL. Вважаю, що ця порада стане в нагоді всім, хто хоче (або потребує) агностичний дизайн бази даних.
Arsen7

@ Arsen7 Що робити, якщо у вас є кілька підприємств - кожен з кількома клієнтами. Ви зберігаєте весь бізнес з електронними адресами своїх клієнтів в одному файлі. Тому ви не можете зробити email_address унікальним, оскільки різні підприємства можуть мати одного клієнта. Тож вам доведеться скласти унікальний унікальний індекс business_id та email_address. Чи можна помістити це в нову таблицю - як пояснено?
Герхард Лібенберг

4
У мене є випадок, коли стовпець "електронної пошти" повинен бути унікальним АБО нульовим. Я мав би створити нову таблицю з єдиним стовпцем "електронна пошта", якби я дотримувався вашої поради. Покладатись на цю специфічну поведінку Mysql набагато простіше, а результат такий же. Клієнту не важливо, зберігаю я електронну пошту в новій таблиці чи ні. Крім того, агностичний дизайн баз даних часто завищений. Для багатьох проектів ви не можете і, ймовірно, не просто переходите з однієї БД в іншу так легко.
conradkleinespel

1
@djmj впевнений, але функціональні залежності важливі для більшості людей, і нульова версія унікального обмеження не застосовує ті ж залежності, що і версія BCNF. Отже, який варіант є більш-менш практичним, може залежати від того, які залежності для вас важливі. Ось чому варто розглянути можливість створення нової таблиці.
nvogel
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.