La colonne Contrainte unique ne peut contenir qu'une seule valeur NULL

Une contrainte unique peut être créée sur une colonne pouvant contenir des valeurs NULL. Cependant, tout au plus, une seule ligne peut contenir une valeur NULL dans cette colonne.

Je ne comprends pas pourquoi c'est le cas puisque, par définition, un NULL n'est pas égal à un autre NULL (puisque NULL est vraiment une valeur inconnue et une valeur inconnue n'est pas égale à une autre valeur inconnue).

Mes questions: 1. Pourquoi est-ce ainsi? 2. Est-ce spécifique à MsSQL?

J'ai l'printing que c'est parce qu'une contrainte unique peut agir comme un champ de reference pour une key étrangère et que le FK ne saurait pas autrement quel logging dans la table de reference à laquelle il faisait reference si plus d'un logging avec NULL existait. Mais, c'est juste une intuition.

(Oui, je comprends que les UC peuvent être sur plusieurs colonnes, mais cela ne change pas la question, mais plutôt la complique un peu.)

Oui, c'est "spécifique" à Microsoft SQL Server (en ce sens que d'autres systèmes de bases de données ont l'approche inverse, celle que vous attendiez – et celle définie dans la norme ANSI, mais je crois qu'il existe d'autres systèmes Serveur).

Si vous travaillez sur une version de SQL Server qui prend en charge les index filtrés, vous pouvez en appliquer un:

CREATE UNIQUE INDEX IX_T ON [Table] ([Column]) WHERE [Column] IS NOT NULL 

(Mais notez que cet index ne peut pas être la cible d'une contrainte FK)


Le «pourquoi» en est vraiment un, c'est comme ça qu'il a été implémenté il y a longtime (peut-être des pré-standards) et c'est une de ces situations embarrassantes où le changer maintenant pourrait potentiellement casser beaucoup de systèmes existants.

Re: Foreign Keys – vous auriez raison, si le fait qu'une valeur NULL dans une colonne de key étrangère ne provoque pas la vérification de la key étrangère – il n'y a aucun moyen (dans SQL Server) d'utiliser NULL comme réel key.

Oui, il s'agit d'une fonctionnalité SQL Server (et une fonctionnalité de quelques autres SGBD) qui est contraire à la norme ISO SQL. Cela n'a peut-être pas beaucoup de sens étant donné la logique appliquée aux valeurs nulles à d'autres endroits dans SQL – mais le standard ISO SQL n'est pas très cohérent à propos de son traitement des valeurs nulles non plus. Le comportement des contraintes d'unicité Nullable dans SQL standard n'est pas très utile. De telles contraintes ne sont pas nécessairement «uniques» du fait qu'elles permettent des duplicates. Par exemple, la contrainte UNIQUE(foo,bar) permet aux lignes suivantes d'exister simultanément dans une table:

 foo bar ------ ------ 999 NULL 999 NULL 

(!)

Évitez les contraintes d'unicité nullables. Il est généralement simple de déplacer les colonnes vers une nouvelle table en tant que colonnes non nullables et d'y mettre la contrainte d'unicité. Les informations qui auraient été représentées en remplissant ces colonnes avec des valeurs nulles peuvent (probablement) être représentées simplement en ne remplissant pas du tout ces colonnes de la nouvelle table.