Dois-je autoriser les valeurs null dans une db schéma?
Je sais que logiquement, il y a certains cas où les valeurs NULL de sens que dans une DB schéma, par exemple si certaines valeurs de la plaine n'ont pas été spécifiés. Cela dit, le travail autour de DBNull dans le code tend à être une douleur royale. Par exemple, si je suis le rendu de la vue, et je veux voir une chaîne, je n'en attendent pas de valeur à une chaîne vide, pas "Null", et je déteste avoir à coder autour de ce scénario.
En outre, il permet l'interrogation de plus facile. Certes, vous pouvez faire "foo n'est pas null" très facilement, mais pour junior SQL devs, c'est contre-intuitif pour ne pas être en mesure d'utiliser "foo != null" (et oui, je sais que sur les options pour désactiver ANSI null, etc, mais ce n'est certainement PAS simple, et je n'aime pas travailler loin de la norme).
Quelle bonne raison est là pour avoir/permettant de valeurs null dans un schéma de base de données?
- Question intéressante. Merci pour le poster. Il apporte un très intéressant point de vue que je n'ai jamais regardé.
- Si nous ne devrions pas utiliser la valeur NULL, pourquoi Sgbdr nous permettre d'utiliser la valeur NULL à tous? Il n'y a rien de mal avec NULL comme longtemps que vous savez comment traiter avec eux. La création des tables distinctes pour stocker des colonnes avec des valeurs null dans chaque scénario est trop trompeuse. Pour voir
NULL
comme le disent lesNA
, essayezSELECT (case when <column> IS NULL then "NA" else <column> end) AS Final FROM <table>
Vous devez vous connecter pour publier un commentaire.
La raison la plus importante pour autoriser les valeurs NULL est qu'il n'existe pas d'alternative raisonnable. Logiquement, une valeur NULL représente "undefined". Pour le manque de valeurs NULL, vous allez finir par essayer de préciser un "dummy" de la valeur partout où le résultat n'est pas défini, et puis vous aurez à rendre compte de dit "factice" de la valeur dans l'ENSEMBLE de la logique de l'application.
J'ai écrit un article de blog sur les raisons, y compris pour les valeurs NULL dans votre base de données. Vous pouvez le trouver ici. En bref, je crois que les valeurs NULL sont une partie intégrante de la conception de base de données, et doit être utilisé le cas échéant.
C. J. Date dans son livre "SQL et la Théorie Relationnelle" (2009: O'Reilly, ISBN 978-0-596-52306-0) prend une position forte contre les valeurs Null. Il démontre que la présence de la valeur Null en SQL donne de mauvaises réponses à certaines questions. (L'argument ne s'applique pas au modèle relationnel lui-même parce que le modèle relationnel ne pas autoriser les valeurs Null.)
Je vais essayer de résumer son exemple dans les mots. Il présente un tableau S avec des attributs SNO (Numéro de Fournisseur) et de la Ville (la Ville où le fournisseur est situé) et d'une ligne: (S1, Londres). Également d'une table de P avec des attributs PNO (Numéro de Pièce) et la Ville (la Ville où une partie est produite) et d'une ligne: (P1, NULL). Maintenant, il ne la requête "Get (SNO,PNO) paires où le fournisseur et une partie des villes sont différentes ou de la partie de la ville n'est pas Paris (ou les deux)."
Dans le monde réel, P1 est produit dans une ville qui est ou n'est pas Paris, de sorte que la requête doit retourner (S1, P1) parce que la partie de la ville soit à Paris ou n'est pas Paris. (La simple présence de P1 dans le tableau P signifie que la pièce a une ville, même s'il est inconnu.) Si c'est Paris, puis le fournisseur et une partie des villes sont différentes. Si ce n'est pas Paris, alors la partie de la ville n'est pas Paris. Cependant, par les règles de la logique tri-valuée, ('London' <> NULL) évalue à l'INCONNU, (NULL <> 'Paris') évalue à l'INCONNU, et l'INCONNU OU une INCONNUE réduit à l'INCONNU, qui n'est pas VRAI (et pas FAUX non plus), et si la ligne n'est pas retournée. Le résultat de la requête "SELECT S. SNO, P. PNO à PARTIR de S, P ou S. de la VILLE <> P. de la VILLE OU de P. de la VILLE <> "Paris" est une table vide, ce qui est la mauvaise réponse.
Je ne suis pas un expert et pas actuellement équipé pour prendre le pro ou le con ici. Je considère C. J. Date pour être l'un des plus grands spécialistes de la théorie relationnelle.
P. S. Il est également vrai que vous pouvez utiliser SQL comme autre chose qu'une base de données relationnelle. Il peut faire beaucoup de choses.
De la théorie du point de vue, avoir un
NULL
signifie que la valeur n'est pas définie pour une colonne.L'utiliser partout où vous avez besoin de dire "je ne sais pas /je n'aime pas" pour répondre à la question "Quelle est la valeur de cette colonne?"
Et voici quelques conseils de la performance du point de vue:
Oracle
,NULL
's ne sont pas indexés. Vous pouvez économiser de l'espace d'index et d'accélérer les requêtes en utilisantNULL
's pour les valeurs que vous n'avez pas besoin d'indice.Oracle
, de fuiteNULL
s'occupent pas d'espace.NULL
's peut être divisé en toute sécurité par.NULL
's ne contribuent enCOUNT(*)
, mais ne contribuent pas dansCOUNT(column)
Les valeurs null sont bonnes lorsque votre colonne peut vraiment avoir une valeur inconnue qui n'a pas de défaut.
Nous ne pouvons pas répondre si votre colonne s'applique à la règle.
par exemple, si vous avez et la date de fin, vous pourriez être tenté de mettre en datetime.maxvalue en tant que par défaut plutôt que des null. il tout à fait valable, mais vous devez prendre en compte le rapport fait sur que et des trucs comme ça.
En théorie, il n'y a pas de différence entre la théorie et la pratique. Dans la pratique, il est.
En théorie, vous pouvez concevoir une base de données que jamais besoin d'un NUL en elle, parce que c'est complètement normalisée. Chaque fois qu'une valeur est omise, l'ensemble de la ligne contenant peut être omis, donc il n'y a pas besoin de NULL.
Toutefois, l'ampleur de la table de décomposition que vous avez à parcourir pour arriver à un tel résultat est tout simplement pas la peine de le gain de l'aspect théorique de l'esthétique. Il est souvent préférable de laisser certaines colonnes contiennent des valeurs NULL.
De bons candidats pour nullable colonnes sont celles où, en plus des données étant facultatif, vous n'êtes jamais à l'aide de la colonne dans une condition de comparaison dans une clause where ou HAVING. Croyez le ou non, les clés étrangères travaillent souvent OK avec des valeurs NULL à eux, pour indiquer une instance d'une relation qui n'est pas présent. Les JOINTURES internes de descendre les valeurs NULL avec les lignes qui les contiennent.
Lorsqu'une valeur est souvent utilisé dans les booléens conditions, il est préférable de la conception de sorte que les valeurs NULL ne se produira pas. Sinon, vous êtes susceptibles de se retrouver avec la mystérieuse raison que, dans le langage SQL, la valeur de "INCONNU" est "INCONNU". Cela a causé des bugs pour un certain nombre de personnes avant vous.
Généralement, si vous le permettez NULL pour une colonne dans une base de données, que la valeur NULL a quelques séparées sens en ce qui concerne la structure de la base de données elle-même. Par exemple, dans le StackOverflow schéma de base de données, la valeur NULL pour le ParentId ou des Étiquettes de colonne dans la table Post indique si le message est une question ou une réponse. Assurez-vous juste que, dans chaque cas, le sens est bien documenté.
Maintenant votre plainte au sujet de la manipulation de ces valeurs dans le code client. Il y a deux façons d'atténuer le problème:
La plupart des cas, avec un sens comme celle décrite ci-dessus ne doit jamais revenir vers le client en premier lieu. Utiliser la valeur NULL dans vos requêtes afin de recueillir les résultats corrects, mais ne retourne pas NULL dans la colonne elle-même.
Pour les autres cas, vous pouvez généralement utiliser des fonctions comme FUSIONNENT() ou la fonction ISNULL() des fonctions pour retourner quelque chose qui est plus facile à traiter.
Une valeur null est utile lorsque vous avez besoin de spécifier qu'il n'existe pas de valeur du tout.
Vous pouvez utiliser un nombre magique à la place, mais c'est plus intuitive pour gérer les valeurs null que de se servir de la magie des valeurs, et il est plus facile de se rappeler la valeur de la poignée. (Hm... c'était à -1 ou 99999 ou 999999 c'était la magie de la valeur...?)
Aussi, de la magie, les valeurs n'ont pas de vraie magie, il n'y a pas de fail safe pour vous garder de l'aide de la valeur de toute façon. L'ordinateur ne sait pas que vous ne pouvez pas multiplier 42 -1 -1 parce que arrive à être une valeur raisonnable dans cette situation, mais il sait que vous ne pouvez pas multiplier 42 avec la valeur null.
Pour une valeur textuelle d'une chaîne vide peut fonctionner comme "sans valeur", mais il ya des inconvénients encore là. Par exemple si vous avez trois espaces dans un champ, il n'est pas toujours possible de distinguer visuellement de la chaîne vide, mais ils sont différents des valeurs.
Les valeurs null et doivent être utilisés à tout moment les informations peuvent ne pas être disponibles au moment où les données d'origine est saisie (par Exemple, la date de livraison sur une commande).
Il y a certainement des situations où les valeurs null peut indiquer la nécessité de la refonte (une table consistant la plupart du temps les entrées null dans la plupart des champs n'est probablement pas correctement normalisé, un dépôt qui contient toutes les valeurs null n'est probablement pas nécessaire.)
De ne pas utiliser les valeurs null parce que votre jr développeurs de ne pas bien comprendre leur indique que vous avez un problème plus important que les valeurs null. Tout développeur qui ne comprennent pas comment accéder à des données qui inclut les valeurs null, doit être donné une formation de base en SQL. C'est aussi stupide que de ne pas à l'aide de déclencheurs pour faire appliquer les règles d'intégrité de données parce que les devs oubliez pas de regarder quand il y a un problème ou non à l'aide de jointures parce que les devs ne pas les comprendre ou à l'aide de select * parce que les devs sont trop paresseux pour ajouter les noms de champ.
Outre les raisons mentionnées dans d'autres réponses NULL peut être très important pour les nouvelles versions de produits existants.
L'ajout d'une nouvelle colonne Nullable à une déjà existante de la table a un impact relativement faible. L'ajout d'une nouvelle colonne non Nullable est beaucoup plus impliqués du fait de la migration des données. Si vous ou vos clients ont beaucoup de données le temps et la complexité de la migration peut devenir un problème important.
Raisons pour avoir les valeurs null
Pour ce que ça vaut, SQL-99 définit un prédicat
IS [NOT] DISTINCT FROM
qui renvoie true ou false, même si les opérandes sont NULLES.Est équivalent à:
PostgreSQL, IBM DB2, et Firebird soutien
IS DISTINCT FROM
.Oracle et Microsoft SQL Server n'est pas (encore).
MySQL a son propre opérateur de
<=>
, qui fonctionne commeIS NOT DISTINCT FROM
.Une base de données est endommagé dans la mesure où il contient une valeur null.
Il n'y a JAMAIS un cas où NULL sens logique. NULL n'est pas une partie du modèle relationnel, et la théorie relationnelle ne dispose pas d'un tel concept comme NULL.
NULL est "utile", dans le sens de merde SGBD du vous laisse pas d'autre choix que de l'utiliser, au niveau PHYSIQUE, que ceux même merde SGBD eux-mêmes gravement confondre avec le niveau logique, et plus ou moins de force à leurs utilisateurs de faire de même.
Je suis d'accord avec la plupart des réponses ici, mais à la phase d'une autre façon, "on ne peut pas avoir une valeur qui signifie deux choses". C'est juste déroutant. Ne 0 réellement moyenne de 0? ou faut-il dire que nous ne savons pas encore? etc.
Quand il y a une entité qui n'a pas de valeur de son attribut, puis nous utilisons une valeur null. Une valeur null n'est pas à 0, mais il n'en est rien de la valeur. Un exemple est la plupart coréen noms ont pas de prénom. Si il y a un attribut de nom avec le prénom, le nom et prénom, une valeur spéciale null doit être donné.
CREATE TABLE MiddleNames (PersonId INT NOT NULL PRIMARY KEY REFERENCES People (Id), MiddleName NVARCHAR(…) NOT NULL)
? – Votre réponse n'explique pas pourquoi unNULL
solution serait préférable sur uneNULL
-moins un.