J'utilise SQL Server 2005. Je veux contraindre les valeurs d'une colonne à être uniques, tout en autorisant NULLS.
Ma solution actuelle implique un index unique sur une vue comme celle-ci:
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)
Des meilleures idées?
sql
sql-server
indexing
constraints
unique
Nuno G
la source
la source
Réponses:
À peu près sûr que vous ne pouvez pas faire cela, car cela viole le but des uniques.
Cependant, cette personne semble avoir un travail décent: http://sqlservercodebook.blogspot.com/2008/04/multiple-null-values-in-unique-index-in.html
la source
À l'aide de SQL Server 2008, vous pouvez créer un index filtré: http://msdn.microsoft.com/en-us/library/cc280372.aspx . (Je vois que Simon a ajouté cela comme un commentaire, mais j'ai pensé que cela méritait sa propre réponse car le commentaire est facilement manqué.)
Une autre option est un déclencheur pour vérifier l'unicité, mais cela pourrait affecter les performances.
la source
create unique index UIX on MyTable (Column1) where Column1 is not null
ANSI_NULLS
c'est leON
cas, sinon vous obtiendrez une erreur en essayant d'insérer des données.L'astuce de colonne calculée est largement connue sous le nom de "nullbuster"; mes notes créditent Steve Kass:
la source
À proprement parler, une colonne NULL unique (ou un ensemble de colonnes) ne peut être NULL (ou un enregistrement de NULL) qu'une seule fois, car avoir la même valeur (et cela inclut NULL) plus d'une fois enfreint évidemment la contrainte d'unicité.
Cependant, cela ne signifie pas que le concept de "colonnes Nullables uniques" est valide; pour l'implémenter dans n'importe quelle base de données relationnelle, nous devons juste garder à l'esprit que ce type de bases de données est censé être normalisé pour fonctionner correctement, et la normalisation implique généralement l'ajout de plusieurs tables supplémentaires (non-entité) pour établir des relations entre les entités .
Prenons un exemple de base en considérant une seule "colonne Nullable unique", il est facile de l'étendre à plusieurs colonnes de ce type.
Supposons que nous les informations représentées par un tableau comme celui-ci:
Nous pouvons le faire en mettant uniqnull à part et en ajoutant une deuxième table pour établir une relation entre les valeurs uniqnull et the_entity (plutôt que d'avoir uniqnull "inside" the_entity):
Pour associer une valeur de uniqnull à une ligne dans the_entity, nous devons également ajouter une ligne dans the_relation.
Pour les lignes de the_entity où aucune valeur uniqnull n'est associée (c'est-à-dire pour celles que nous placerions NULL dans the_entity_incorrect), nous n'ajoutons simplement pas de ligne dans the_relation.
Notez que les valeurs pour uniqnull seront uniques pour toute la_relation, et notez également que pour chaque valeur de l'entité, il peut y avoir au plus une valeur dans la_relation, puisque les clés primaires et étrangères sur celle-ci imposent cela.
Ensuite, si une valeur de 5 pour uniqnull doit être associée à un id the_entity de 3, nous devons:
Et, si une valeur id de 10 pour the_entity n'a pas d'équivalent unique, nous faisons seulement:
Pour dénormaliser ces informations et obtenir les données qu'une table comme the_entity_incorrect contiendrait, nous devons:
L'opérateur "jointure externe gauche" garantit que toutes les lignes de l'entité apparaîtront dans le résultat, en plaçant NULL dans la colonne uniqnull lorsqu'aucune colonne correspondante n'est présente dans the_relation.
N'oubliez pas que tout effort passé pendant quelques jours (ou semaines ou mois) à concevoir une base de données bien normalisée (et les vues et procédures de dénormalisation correspondantes) vous fera économiser des années (ou des décennies) de douleur et de gaspillage de ressources.
la source