¿MySQL ignora los valores nulos en restricciones únicas?
289
Tengo una columna de correo electrónico que quiero ser única. Pero también quiero que acepte valores nulos. ¿Puede mi base de datos tener 2 correos electrónicos nulos de esa manera?
Sí, MySQL permite múltiples NULL en una columna con una restricción única.
CREATETABLE table1 (x INT NULLUNIQUE);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:
xNULLNULL1
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.
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
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 UNIQUENULLvalor?"
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 UNIQUENULLvalor". 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 UNIQUENULLvalor, 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.
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.
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.
Respuestas:
Sí, MySQL permite múltiples NULL en una columna con una restricción única.
Resultado:
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.
fuente
WHERE column IS NOT NULL
parece fallarme, ya que no es compatible con mi versión de MySQL. ¿Alguien sabe dónde podría mirar?De los documentos :
Esto se aplica a todos los motores excepto BDB .
fuente
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
NULL
valores duplicados mientras se usaUNIQUE
?" O "¿Cómo permitir solo unUNIQUE
NULL
valor?"La pregunta ya ha sido respondida, sí, puede tener
NULL
valores duplicados mientras usa elUNIQUE
índice.Como me topé con esta respuesta mientras buscaba "cómo permitir un
UNIQUE
NULL
valor". 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
NULL
valor, sin embargo, puede tener unUNIQUE
valor 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.
fuente
UNIQUE
restricción sino por laNOT NULL
restricción. Creo que esta respuesta es irrelevante para la pregunta porque la pregunta es específicamente sobre el comportamiento de laUNIQUE
restricción.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.
fuente