¿MySQL ignora los valores nulos en restricciones únicas?

Respuestas:

423

Sí, MySQL permite múltiples NULL en una columna con una restricción única.

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;

Resultado:

x
NULL
NULL
1

Esto no es cierto para todas las bases de datos. SQL Server 2005 y versiones anteriores, por ejemplo, solo permiten un único valor NULL en una columna que tiene una restricción única.

Mark Byers
fuente
37
excelente comentario sobre cómo es cierto en mysql, pero no necesariamente en general.
user2910265
11
Según las preguntas frecuentes de SQLite , el comportamiento es el mismo en MySQL, PostgreSQL, SQLite, Oracle y Firebird.
Amir Ali Akbari
44
Por favor actualice su respuesta. SQLServer 2008+ lo permite absolutamente, simplemente tiene que agregar una cláusula WHERE ... en 2017, nadie debería tener una versión anterior a 2008 de todos modos ... stackoverflow.com/questions/767657/…
Mathieu Turcotte
Esta pequeña característica ha sido muy difícil de encontrar una respuesta que no requiera agregar una nueva columna a la base de datos o actualizar MySQL en una aplicación muy antigua. Realmente estaba buscando una solución como Postgres donde pueda usar COALESCE, pero parece que la respuesta siempre es que no es un error, como está diseñado. Ni siquiera WHERE column IS NOT NULLparece fallarme, ya que no es compatible con mi versión de MySQL. ¿Alguien sabe dónde podría mirar?
newdark-it
1
nota: esto también funciona también índices únicos que tienen más columnas. Entonces, si desea que las columnas a, byc sean únicas, aún puede tener en la tabla filas dobles con nulo, b, c
Mihai Crăiță
111

De los documentos :

"un índice ÚNICO permite múltiples valores NULL para columnas que pueden contener NULL"

Esto se aplica a todos los motores excepto BDB .

Matthew Flaschen
fuente
3
BDB ya no está disponible en las versiones actuales de mysql (comenzando con 5.1.12).
Alim Özdemir
1
Mis pruebas parecen mostrar que la base de datos Java Derby v10.13.1.1. de manera similar, solo permite un nulo en una columna con un índice único.
chrisinmtown
7

No estoy seguro si el autor originalmente solo preguntaba si esto permite o no valores duplicados o si hubo una pregunta implícita aquí preguntando, "¿Cómo permitir NULLvalores duplicados mientras se usa UNIQUE?" O "¿Cómo permitir solo un UNIQUE NULLvalor?"

La pregunta ya ha sido respondida, sí, puede tener NULLvalores duplicados mientras usa el UNIQUEíndice.

Como me topé con esta respuesta mientras buscaba "cómo permitir un UNIQUE NULLvalor". Para cualquier otra persona que pueda tropezar con esta pregunta mientras hace lo mismo, el resto de mi respuesta es para usted ...

En MySQL no puede tener un UNIQUE NULLvalor, sin embargo, puede tener un UNIQUEvalor vacío insertando con el valor de una cadena vacía.

Advertencia: los valores numéricos y distintos de cadenas pueden tener un valor predeterminado de 0 u otro valor predeterminado.

bluegman991
fuente
1
La restricción no tiene nada que ver con el índice. De hecho, ni siquiera podrá tener una sola fila con valor NULL a pesar del hecho de que no hay otra fila similar.
Pijusn
1
@Pijusn ¿Qué quiere decir con "restricción no tiene nada que ver con el índice?" También sobre su segunda oración, nunca dije que podría tener una fila con un valor NULL, es por eso que dije al comienzo de la publicación, que esta es una solución solo si no está configurado para usar valores nulos.
bluegman991
Lo que quise decir es que agregar un nuevo elemento falla no por la UNIQUErestricción sino por la NOT NULLrestricción. Creo que esta respuesta es irrelevante para la pregunta porque la pregunta es específicamente sobre el comportamiento de la UNIQUErestricción.
Pijusn
@Pijusn te tengo. Tienes razón, he eliminado la redacción que sugiere lo contrario. Leí mal la pregunta. Pero creo que la respuesta aún puede ser útil para los usuarios que tropiezan con esta pregunta como lo hice mientras intentaba encontrar una manera de tener un valor único de "nada", pero están permitiendo erróneamente la capacidad nula.
bluegman991
1
Encontré esta respuesta útil. Sin embargo, también se responde aquí . Esta publicación fue el primer resultado de mi búsqueda en Google, aunque esta respuesta y la pregunta vinculada eran lo que estaba buscando.
kingledion
5

Evite restricciones únicas anulables. Siempre puede colocar la columna en una nueva tabla, hacerla no nula y única y luego llenar esa tabla solo cuando tenga un valor para ella. Esto asegura que cualquier dependencia clave en la columna se pueda aplicar correctamente y evita cualquier problema que pueda ser causado por nulos.

nvogel
fuente
66
Sí, pero lo que propones es casi exactamente lo que mysql hace detrás de escena. ¿Por qué reinventar la rueda si esta funcionalidad está integrada?
ProfileTwist
2
Porque no es SQL válido. Creo que este consejo será útil para todos los que quieran (o necesiten) un diseño agnóstico de base de datos.
Arsen7
@ Arsen7 ¿Qué sucede si tiene varias empresas, cada una con varios clientes? Usted almacena todos los negocios con las direcciones de correo electrónico de sus clientes en un solo archivo. Por lo tanto, no puede hacer que email_address sea única porque diferentes empresas pueden tener el mismo cliente. Por lo tanto, debe crear un índice único compuesto de business_id y email_address. ¿Es posible poner esto en una nueva tabla, como se explicó?
Gerhard Liebenberg
44
Tengo un caso en el que una columna de "correo electrónico" debe ser única O nula. Tendría que crear una nueva tabla con una sola columna de "correo electrónico" si tuviera que seguir sus consejos. Confiar en este comportamiento específico de Mysql es mucho más fácil y el resultado es el mismo. Al cliente no le importa si guardo el correo electrónico en una nueva tabla o no. Además, el diseño agnóstico de la base de datos está a menudo sobrevalorado. Para muchos proyectos, no puede y probablemente no cambie de una base de datos a otra tan fácilmente.
conradkleinespel
1
@djmj seguro, pero las dependencias funcionales son importantes para la mayoría de las personas y la versión de restricción única anulable no impone las mismas dependencias que la versión BCNF. Entonces, qué opción es más o menos práctica puede depender de qué dependencias sean importantes para usted. Es por eso que vale la pena considerar crear una nueva tabla.
nvogel