Estoy usando SQL Server 2005. Quiero restringir los valores en una columna para que sean únicos, mientras se permiten NULLS.
Mi solución actual implica un índice único en una vista como esta:
CREATE VIEW vw_unq WITH SCHEMABINDING AS
SELECT Column1
FROM MyTable
WHERE Column1 IS NOT NULL
CREATE UNIQUE CLUSTERED INDEX unq_idx ON vw_unq (Column1)
¿Alguna idea mejor?
sql
sql-server
indexing
constraints
unique
Nuno G
fuente
fuente
Respuestas:
Estoy bastante seguro de que no puede hacer eso, ya que viola el propósito de los únicos.
Sin embargo, esta persona parece tener un trabajo decente alrededor: http://sqlservercodebook.blogspot.com/2008/04/multiple-null-values-in-unique-index-in.html
fuente
Con SQL Server 2008, puede crear un índice filtrado: http://msdn.microsoft.com/en-us/library/cc280372.aspx . (Veo que Simon agregó esto como comentario, pero pensé que merecía su propia respuesta ya que el comentario se pasa por alto fácilmente).
Otra opción es un disparador para verificar la unicidad, pero esto podría afectar el rendimiento.
fuente
create unique index UIX on MyTable (Column1) where Column1 is not null
ANSI_NULLS
seaON
, de lo contrario obtendrá un error al intentar insertar datos.El truco de la columna calculada es ampliamente conocido como "nullbuster"; mis notas le dan crédito a Steve Kass:
fuente
Estrictamente hablando, una columna única que acepta valores NULL (o un conjunto de columnas) puede ser NULL (o un registro de NULL) solo una vez, ya que tener el mismo valor (y esto incluye NULL) más de una vez obviamente viola la restricción única.
Sin embargo, eso no significa que el concepto de "columnas únicas que aceptan valores NULL" sea válido; para implementarlo realmente en cualquier base de datos relacional solo tenemos que tener en cuenta que este tipo de bases de datos están destinadas a ser normalizadas para que funcionen correctamente, y la normalización generalmente implica la adición de varias tablas adicionales (no entidades) para establecer relaciones entre las entidades .
Trabajemos con un ejemplo básico considerando solo una "columna única que acepta valores NULL", es fácil expandirla a más columnas de este tipo.
Supongamos que tenemos la información representada por una tabla como esta:
Podemos hacerlo separando uniqnull y agregando una segunda tabla para establecer una relación entre los valores uniqnull y the_entity (en lugar de tener uniqnull "dentro" de the_entity):
Para asociar un valor de uniqnull a una fila en the_entity, también debemos agregar una fila en the_relation.
Para las filas en the_entity donde no hay valores uniqnull asociados (es decir, para los que pondríamos NULL en the_entity_incorrect) simplemente no agregamos una fila en the_relation.
Tenga en cuenta que los valores de uniqnull serán únicos para toda la relación, y también observe que para cada valor en la_entidad puede haber como máximo un valor en la relación, ya que las claves primaria y externa imponen esto.
Entonces, si un valor de 5 para uniqnull se va a asociar con un id de the_entity de 3, necesitamos:
Y, si un valor de id de 10 para the_entity no tiene una contraparte uniqnull, solo hacemos:
Para desnormalizar esta información y obtener los datos que tendría una tabla como the_entity_incorrect, necesitamos:
El operador "unión externa izquierda" asegura que todas las filas de the_entity aparecerán en el resultado, poniendo NULL en la columna uniqnull cuando no haya columnas coincidentes en the_relation.
Recuerde, cualquier esfuerzo invertido durante algunos días (o semanas o meses) en diseñar una base de datos bien normalizada (y las correspondientes vistas y procedimientos desnormalizantes) le ahorrará años (o décadas) de dolor y recursos desperdiciados.
fuente