Fondamentalement parlant, n'est pas une valeur NULL dans un multi-colonne de clé primaire. Mais en avoir une a des implications le concepteur n'a pas l'intention, c'est pourquoi de nombreux systèmes de jeter une erreur lorsque vous essayez ceci.
Prenons le cas du module/les versions des paquets stockés comme une série de domaines:
CREATE TABLE module
(name varchar(20) PRIMARY KEY,
description text);
CREATE TABLE version
(module varchar(20) REFERENCES module,
major integer NOT NULL,
minor integer DEFAULT 0 NOT NULL,
patch integer DEFAULT 0 NOT NULL,
release integer DEFAULT 1 NOT NULL,
ext varchar(20),
notes text NOT NULL,
PRIMARY KEY (module, major, minor, patch, release, ext));
Les 5 premiers éléments de la clé primaire sont régulièrement définies parties de la version en cours, mais certains paquets ont une extension personnalisé qui n'est généralement pas un nombre entier (comme "rc-foo" ou "vanille" ou "beta" ou que ce soit d'autre, quelqu'un pour qui les quatre champs est insuffisante peut rêver). Si un colis n'est pas une extension, alors elle est NULLE dans le modèle ci-dessus, et aucun mal ne serait fait en laissant les choses de cette façon.
Mais ce qui est NULL? Il est censé représenter un manque d'information, un inconnu. Cela dit, peut-être que cela fait plus de sens:
CREATE TABLE version
(module varchar(20) REFERENCES module,
major integer NOT NULL,
minor integer DEFAULT 0 NOT NULL,
patch integer DEFAULT 0 NOT NULL,
release integer DEFAULT 1 NOT NULL,
ext varchar(20) DEFAULT '' NOT NULL,
notes text NOT NULL,
PRIMARY KEY (module, major, minor, patch, release, ext));
Dans cette version "ext" une partie de la tuple n'est PAS NULLE, mais par défaut est une chaîne vide, qui est sémantiquement (et pratiquement) est différente de NULL. Une valeur NULL est un inconnu, alors qu'une chaîne vide est une volonté délibérée de la définition de "quelque chose de pas être présent". En d'autres termes, "vide" et "null" sont des choses différentes. Son la différence entre "je n'ai pas de valeur ici" et "je ne sais pas ce que la valeur est ici."
Lorsque vous vous inscrivez un paquet qui n'a pas de version de l'extension que vous savez qu'il manque une extension, alors une chaîne vide est en fait la valeur correcte. Un NUL ne serait correcte si vous ne savais pas si elle avait eu une extension ou non. Cette situation est plus facile de traiter avec les systèmes où les valeurs de chaîne sont la norme, car il n'y a aucun moyen de représenter un "vide integer" autre que l'insertion de 0 ou 1, qui sera le vent en cours de déploiement dans toute comparaison faite plus tard (qui a ses propres conséquences).
D'ailleurs, les deux façons sont valables dans Postgres (puisque nous allons discuter de "l'entreprise" RDMBSs), mais les résultats de la comparaison peuvent varier un peu quand vous jetez une valeur NULL dans le mix -- parce que NULL == "ne sait pas" donc tous les résultats d'une comparaison avec une valeur NULL vent jusqu'à être NULLE puisque vous ne pouvez pas savoir quelque chose qui est inconnu. Donc cela peut être une source de bogues subtils lors des opérations de tri, de les comparer, etc. Postgres suppose que vous êtes un adulte et peut prendre cette décision pour vous-même. Oracle et DB2 suppose que vous ne savais pas que vous faisiez quelque chose de stupide et de lever une erreur. C'est généralement la bonne chose, mais pas toujours, vous pouvez effectivement ne pas savoir et avoir une valeur NULL dans certains cas et, partant, une ligne avec un inconnu contre lequel des comparaisons significatives sont impossible est le comportement correct.
Dans tous les cas, vous devez vous efforcer d'éliminer le nombre de champs NULL vous permettre à travers l'ensemble du schéma et doublement quand il s'agit de domaines qui font partie de la clé primaire. Dans la grande majorité des cas, la présence de colonnes NULL est une indication de l'onu-normalisé (par opposition délibérée de-normalisée) schéma de conception et doit être pensé très fort avant d'être accepté.