Je me souviens avoir lu cet article sur la conception de base de données et je me souviens également que vous aviez besoin de propriétés de champ NOT NULL. Je ne me souviens pas pourquoi c'était le cas cependant.
Tout ce que je peux sembler penser, c’est que, en tant que développeur d’applications, vous n’auriez pas à tester NULL et une valeur de donnée inexistante éventuelle (par exemple, une chaîne vide pour des chaînes).
Mais que faites-vous dans le cas des dates, de l'heure et de l'heure (SQL Server 2008)? Vous devez utiliser une date historique ou une date limite.
Des idées à ce sujet?
database-design
null
Thomas Stringer
la source
la source
Réponses:
Je pense que la question est mal formulée, car le libellé implique que vous avez déjà décidé que les valeurs NULL sont mauvaises. Peut-être que vous vouliez dire "Faut-il autoriser les valeurs NULL?"
Quoi qu'il en soit, voici mon point de vue: je pense que les valeurs NULL sont une bonne chose. Lorsque vous commencez à empêcher les valeurs NULL simplement parce que "les valeurs NULL sont mauvaises" ou "les valeurs NULL sont difficiles", vous commencez à créer des données. Par exemple, si vous ne connaissez pas ma date de naissance? Qu'allez-vous mettre dans la colonne jusqu'à ce que vous sachiez? Si vous ressemblez à beaucoup de gens anti-NULL, vous allez entrer 1900-01-01. Maintenant, je vais être placé dans le service de gériatrie et recevoir probablement un appel de la station de nouvelles locale me félicitant pour ma longue vie, me demandant mes secrets pour vivre une si longue vie, etc.
Si une ligne peut être entrée où il est possible que vous ne connaissiez pas la valeur d'une colonne, je pense que NULL est beaucoup plus logique que de choisir une valeur de jeton arbitraire pour représenter le fait qu'elle est inconnue - une valeur que d'autres vont utiliser. devez déjà savoir, faire de l’ingénierie inverse ou demander aux alentours de comprendre ce que cela signifie.
Cependant, il existe un équilibre: toutes les colonnes de votre modèle de données ne doivent pas être nulles. Un formulaire contient souvent des champs facultatifs ou des informations qui, autrement, ne sont pas collectées au moment de la création de la ligne. Mais cela ne signifie pas que vous pouvez différer le remplissage de toutes les données. :-)
De plus, la capacité d'utiliser NULL peut être limitée par des exigences cruciales dans la vie réelle. Dans le domaine médical, par exemple, il peut être très difficile de savoir pourquoi une valeur est inconnue. La fréquence cardiaque est-elle NULL parce qu'il n'y a pas eu de pouls ou parce que nous ne l'avons pas encore mesuré? Dans un tel cas, pouvons-nous mettre NULL dans la colonne de fréquence cardiaque et avoir des notes ou une colonne différente avec une raison NULL?
N'ayez pas peur des NULL, mais soyez disposé à apprendre ou à dicter quand et où ils devraient être utilisés, et quand et où ils ne devraient pas.
la source
birth_date
laquelle vous stockez les dates de naissance? Si la date de naissance est inconnue, alors n'insérez pas la date de naissance dansbirth_date
. Les nullités sont un désastre.1900-01-01
pour éviter d'avoir une valeur date / heure NULL? Alors ok. En outre, NULL = inconnu et inconnu = faux. Je ne suis pas sûr des problèmes que cela pourrait causer, si ce n'est que les gens ne sont pas nés en sachant cela (comme ils ne sont pas nés en sachant beaucoup de choses inhérentes à un SGBDR complexe). Encore une fois, agitant les mains et disant "Problème! Désastre!" ne le rend pas ainsi.Les raisons établies sont:
NULL n'est pas une valeur et n'a donc aucun type de données intrinsèque. Les valeurs null nécessitent une gestion spéciale partout où un code reposant sur des types réels peut également recevoir la valeur NULL non typée.
NULL rompt la logique à deux valeurs (vrai ou faux) et requiert une logique à trois valeurs. Ceci est bien plus complexe à mettre en œuvre même correctement, et il est certainement mal compris par la plupart des administrateurs de base de données et à peu près tous les non-administrateurs de base de données. En conséquence, il invite positivement de nombreux bugs subtils dans l'application.
La signification sémantique de toute valeur NULL spécifique est laissée à l'application , contrairement aux valeurs réelles.
Des sémantiques telles que «non applicable», «inconnu» et «sentinelle» sont courantes, mais il en existe d'autres. Ils sont fréquemment utilisés simultanément dans la même base de données, même dans la même relation; et sont bien sûr des significations inexplicables, indiscernables et incompatibles .
Ils ne sont pas nécessaires pour les bases de données relationnelles , comme expliqué dans «Comment traiter les informations manquantes sans null» . Une normalisation plus poussée est une première étape évidente pour essayer de débarrasser une table de valeurs NULL.
Cela ne signifie pas que NULL ne devrait jamais être autorisé. Il ne soutiennent qu'il ya beaucoup de bonnes raisons de pas les valeurs NULL chaque fois que possible.
De manière significative, il plaide en faveur d'essais très durs - via une meilleure conception de schéma, des moteurs de base de données améliorés et des langages de base de données encore meilleurs - afin de permettre d'éviter plus souvent la valeur NULL.
Fabian Pascal répond à plusieurs arguments dans «Nulls Nullified» .
la source
Je ne suis pas d'accord, les valeurs nulles sont un élément essentiel de la conception d'une base de données. Comme vous l'avez également mentionné, l'alternative serait une prolifération de valeurs connues représentant les disparus ou les inconnus. Le problème réside dans le fait que null est si largement incompris et, par conséquent, utilisé de manière inappropriée.
IIRC, Codd a suggéré que la mise en œuvre actuelle de null (signifiant non présent / manquant) pourrait être améliorée en disposant de deux marqueurs nuls au lieu d’un, "non présent mais applicable" et "non présent et non applicable". Je ne peux pas imaginer comment cela améliorerait personnellement les conceptions relationnelles.
la source
null
, et une logique à valeurs multiples définie par l'utilisateur pour aller avec eux: pPermettez-moi de commencer par dire que je ne suis pas administrateur de base de données, mais que je suis un développeur par cœur et que je gère et met à jour nos bases de données en fonction de nos besoins. Cela étant dit, j'avais la même question pour plusieurs raisons.
Je passe très longtemps à parcourir les tonnes de réponses, commentaires, articles et conseils sur Internet. Inutile de dire que la plupart des informations étaient à peu près les mêmes que la réponse de @ AaronBertrand. C'est pourquoi j'ai ressenti le besoin de répondre à cette question.
Premièrement, je veux mettre quelque chose au clair pour tous les lecteurs à venir ... Les valeurs NULL représentent des données inconnues PAS des données inutilisées. Si vous avez une table d'employés avec un champ de date de fin. Une valeur nulle dans la date de fin est parce qu'il s'agit d'un futur champ obligatoire qui est actuellement inconnu. Chaque employé, qu’il soit actif ou licencié, aura à un moment donné une date ajoutée à ce champ. C’est à mon avis la seule et unique raison d’un champ Nullable.
Cela étant dit, la même table employee contiendrait probablement une sorte de données d'authentification. Il est courant dans un environnement d'entreprise que les employés soient répertoriés dans la base de données pour les ressources humaines et la comptabilité, mais ils ne disposent pas toujours des informations d'authentification nécessaires. La plupart des réponses vous laisseraient croire qu'il est acceptable de supprimer ces champs ou de créer un compte pour eux, mais de ne jamais leur envoyer les informations d'identification. Dans le premier cas, votre équipe de développement rédigera du code pour rechercher les NULL et les traiter en conséquence, ce qui représente un risque énorme pour la sécurité! Les comptes qui ne sont pas encore utilisés dans le système ne font qu'augmenter le nombre de points d'accès possibles pour un pirate informatique.
Compte tenu des informations ci-dessus, le meilleur moyen de traiter les données nullables qui SERONT utilisées consiste à autoriser les valeurs Nullables. C'est triste mais vrai et vos développeurs vont vous détester pour cela. Le deuxième type de données nullable doit être placé dans une table liée (IE: compte, informations d'identification, etc.) et avoir une relation un à un. Cela permet à un utilisateur d'exister sans informations d'identification, sauf si elles sont nécessaires. Cela supprime le risque supplémentaire de sécurité, l'espace précieux dans la base de données et fournit une base de données beaucoup plus propre.
Vous trouverez ci-dessous une structure de tableau très simpliste montrant à la fois la colonne Nullable requise et une relation un-à-un.
Je sais que je suis un peu en retard pour le parti depuis que cette question a été posée il y a des années, mais j'espère que cela contribuera à éclaircir cette question et la meilleure façon de la gérer.
la source
TerminationDate
enregistrements d'employés, mais une table pourTerminatedEmployee
laquelle les employés sont déplacés (non copiés) par l'application lorsqu'ils sont résiliés. Évidemment, cela fonctionne bien avec la table Account car il n'y aura pas de compte lié sur laTerminatedEmployee
table. Si vous avez toujours besoin des numéros de téléphone, je voudrais inverser les clés étrangères afin que les tables des employés et des employés terminés aient l'identifiant du numéro de téléphone et non l'inverse.Mis à part tous les problèmes avec les développeurs NULL déroutants, les NULL présentent un autre inconvénient très grave: les performances.
Les colonnes NULL'able sont un désastre du point de vue des performances. Prenons l'exemple de l'arithmétique des nombres entiers. Dans un monde sain sans NULL, il est "facile" de vectoriser une arithmétique entière dans le code du moteur de base de données à l'aide d'instructions SIMD pour effectuer à peu près tous les calculs à une vitesse supérieure à 1 ligne par cycle de processeur. Cependant, au moment où vous introduisez NULL, vous devez gérer tous les cas spéciaux créés par NULL. Les jeux d'instructions modernes de la CPU (lire: x86 / x64 / ARM et la logique du GPU) ne sont tout simplement pas équipés pour le faire efficacement.
Considérez la division comme exemple. À un niveau très élevé, voici la logique dont vous avez besoin avec un entier non nul:
Avec NULL, cela devient un peu plus compliqué. Ensemble avec
b
vous aurez besoin d'un indicateur sib
est nul et similaire poura
. Le chèque devient maintenant:L'arithmétique NULL est beaucoup plus lente à s'exécuter sur un processeur moderne que l'arithmétique non nulle (par un facteur d'environ 2-3x).
Cela empire lorsque vous introduisez SIMD. Avec SIMD, un processeur Intel moderne peut effectuer 4 divisions entières de 32 bits en une seule instruction, comme ceci:
Maintenant, il existe aussi des moyens de gérer NULL dans les versions SIMD, mais cela nécessite d’utiliser davantage de vecteurs et de registres de CPU et de faire un masquage de bits intelligent. Même avec de bons tricks, la pénalité de performance de l'arithmétique NULL des entiers s'insinue dans la plage 5-10x plus lente, même pour des expressions relativement simples.
Quelque chose comme ce qui précède est valable pour les agrégats et, dans une certaine mesure, pour les jointures.
En d'autres termes: L'existence de NULL dans SQL est une incompatibilité d'impédance entre la théorie de la base de données et la conception même des ordinateurs modernes. Il y a une bonne raison pour que NULL déroute les développeurs - car un entier ne peut pas être NULL dans la plupart des langages de programmation sains - ce n'est tout simplement pas le fonctionnement des ordinateurs.
la source
Des questions intéressantes.
C'est plus compliqué que ça. Null a un certain nombre de significations distinctes et une des raisons vraiment importantes de ne pas autoriser les valeurs nulles dans de nombreuses colonnes est que, lorsque la colonne est nulle, cela signifie alors une seule et unique chose (à savoir qu'elle ne figure pas dans une jointure externe). De plus, cela vous permet de définir des normes minimales de saisie de données, ce qui est très utile.
Cela illustre tout de suite un problème avec les valeurs NULL, à savoir qu'une valeur stockée dans une table peut signifier "cette valeur ne s'applique pas" ou "nous ne savons pas". Avec les chaînes, une chaîne vide peut servir de "cela ne s'applique pas", mais avec les dates et les heures, il n'y a pas de convention de ce type car il n'y a pas de valeur valide qui signifie conventionnellement cela. Typiquement, vous serez bloqué avec NULL.
Il existe des moyens de contourner ce problème (en ajoutant plus de relations et en joignant des liens), mais ceux-ci posent exactement le même problème de clarté sémantique que la présence de NULL dans la base de données. Pour ces bases de données, je ne m'inquiéterais pas pour ça. Vous ne pouvez vraiment rien y faire.
EDIT: Un domaine dans lequel les valeurs NULL sont indispensables est celui des clés étrangères. Ici, ils n'ont généralement qu'un seul sens, identique au null dans le sens de jointure externe. C'est une exception au problème bien sûr.
la source
L'article de Wikipedia sur SQL Null contient des remarques intéressantes sur la valeur NULL et, en tant que réponse indépendante de la base de données, tant que vous êtes conscient des effets potentiels de l'utilisation de valeurs NULL pour votre SGBDR spécifique, elles sont acceptables dans votre conception. Sinon, vous ne pourriez pas spécifier de colonnes nullables.
Sachez simplement comment votre SGBDR les gère dans les opérations SELECT telles que les mathématiques, ainsi que dans les index.
la source
Wow, la bonne réponse "N'autorisez pas les valeurs NULL lorsque vous n'êtes pas obligé de le faire, car elles dégradent les performances" est en quelque sorte la dernière réponse notée. Je vais le voter et élaborer. Lorsqu'un SGBDR autorise les valeurs NULL pour une colonne non fragmentée, cette colonne est ajoutée à une image bitmap qui indique si la valeur est NULL pour chaque ligne. Ainsi, en ajoutant une capacité NULL à une colonne d'une table où toutes les colonnes n'autorisent pas les valeurs NULL, vous augmentez l'espace de stockage requis pour enregistrer la table. De plus, vous demandez au SGBDR de lire et d’écrire dans le bitmap, ce qui nuit aux performances de toutes les opérations.
En outre, dans un certain nombre de cas, autoriser des valeurs NULL rompra 3NF. Bien que je ne sois pas un collant pour 3NF comme bon nombre de mes collègues, considérons le scénario suivant:
Dans la table Personne, il existe une colonne, appelée DateOfDeath, qui est nullable. Si une personne est décédée, son DateOfDeath sera renseigné, sinon, il sera laissé à NULL. Il existe également une colonne de bits non nullable appelée IsAlive. Cette colonne est définie sur 1 si la personne est en vie et sur 0 si la personne est morte. La grande majorité des procédures stockées utilisent la colonne IsAlive, elles ne s’intéressent que si une personne est en vie, et non leur DateOfDeath.
Cependant, la colonne IsAlive interrompt la normalisation de la base de données, car elle est complètement dérivable de DateOfDeath. Mais comme IsAlive est câblé dans la majorité des fournisseurs de services, la solution simple consiste à rendre DateOfDeath non nullable et à attribuer une valeur par défaut à la colonne dans le cas où la personne est toujours en vie. Les quelques SP qui utilisent DateOfDeath peuvent ensuite être réécrits pour vérifier la colonne IsAlive et n'honorer DateOfDeath que si la personne n'est pas en vie. Encore une fois, étant donné que la majorité des fournisseurs de services s'intéressent uniquement à IsAlive (un peu) et non à DateOfDeath (une date), l’utilisation de ce modèle accélère considérablement l’accès.
Un script T-SQL utile pour rechercher des colonnes Nullable sans NULL dans tous les schémas est:
Si vous exécutez cette opération sur une copie de votre base de données de production, vous pouvez trouver les colonnes de développeurs marquées comme autorisant les valeurs NULL ne contenant pas de valeur NULL dans la pratique. La grande majorité d'entre eux peuvent être marqués comme NOT NULL, augmentant ainsi les performances et diminuant l'espace de stockage.
Il se peut qu'il ne soit pas possible d'éliminer tous les NULL de toutes les tables tout en conservant une conception propre, mais l'élimination du plus grand nombre possible de NULL présente un avantage considérable. L'optimiseur fonctionne beaucoup plus rapidement avec ces informations et si vous pouvez éliminer toutes les valeurs NULL d'une table, vous pouvez récupérer une quantité considérable d'espace de stockage.
Je sais que les administrateurs de bases de données ne pensent pas vraiment aux performances, mais vous ne pouvez utiliser qu'une solution limitée, avec une quantité de mémoire et de puissance de processeur maximale. Vous devrez commencer à penser à la conception physique et logique. .
Notez également que cela ne concerne que les vrais SGBDR et que je base la partie technique de mes réponses sur SQL Server. Le T-SQL répertorié pour rechercher les colonnes Nullable sans NULL provient également de SQL Server.
la source