Pourquoi ne devrions-nous pas autoriser les valeurs NULL?

125

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?

Thomas Stringer
la source
4
Cette réponse donne un aperçu de l'utilisation de NULL dba.stackexchange.com/questions/5176/…
Derek Downey
10
Vraiment? Pourquoi les SGBDR nous permettent-ils d'utiliser NULL, si nous ne devrions pas les utiliser? Il n'y a rien de mal avec NULL tant que vous savez comment les gérer.
Fr0zenFyr
3
S'agissait-il d'une modélisation de données BI? En règle générale, vous ne devez pas autoriser les tables NULL dans les tables NULL ... sinon, les NULL sont vos amis quand ils sont utilisés correctement. =)
sam yi le
2
@ Fr0zenFyr, juste parce qu'un SGBDR nous permet de faire quelque chose, ce n'est pas nécessairement une bonne idée de le faire. Rien ne nous oblige à déclarer une clé primaire ou une clé unique dans une table, mais nous le faisons de toute façon à quelques exceptions près.
Lennart
3
Je pense qu'un traitement complet de ce sujet devrait faire référence à l'exigence initiale de Codd selon laquelle un SGBDR doit avoir un moyen systématique de traiter les données manquantes. Dans le monde réel, il existe des situations dans lesquelles un emplacement pour les données est créé, mais il n'y a pas de données à insérer. L’architecte de données doit apporter une réponse à cette question, qu’il s’agisse de la conception de base de données, de la programmation d’applications ou des deux. Le SQL NULL est loin d'être parfait pour répondre à cette exigence, mais c'est mieux que rien du tout.
Walter Mitty

Réponses:

230

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.

Aaron Bertrand
la source
3
"une certaine valeur de jeton arbitraire pour représenter le fait qu'il est inconnu", on l'appelle une valeur sentinelle
Alexander
4
Mais qu'est-ce qui vous empêche de créer une table séparée dans birth_datelaquelle vous stockez les dates de naissance? Si la date de naissance est inconnue, alors n'insérez pas la date de naissance dans birth_date. Les nullités sont un désastre.
Eldar Agalarov
6
@EldarAgalarov Cela sonne comme le raisonnement de Trump ("catastrophe" pourquoi? Comment? Pour qui? Votre opinion que quelque chose est une "catastrophe" ne le rend pas ainsi). Quoi qu'il en soit, la date de naissance n'est qu'un exemple. Si vous avez du personnel, des membres ou des clients qui ont 15 colonnes potentiellement nullables, allez-vous créer 15 tables secondaires? Et si vous en avez 50? Et si votre table de faits DW en avait 500? La maintenance pour empêcher les NULL effrayants de votre base de données devient 10 fois plus grave que n'importe quel "désastre" dont vous avez peur ...
Aaron Bertrand
3
@AaronBertrand si votre table a 15 colonnes potentiellement nullables, cela sent vraiment mauvais ^^ Non pas qu'un nombre énorme de colonnes soit intrinsèquement mauvais, mais cela peut indiquer une mauvaise conception OU une dénormalisation requise. Mais cela soulèvera des questions.
programaths
2
@Wildcard Vous n'avez donc jamais vu de gens stocker 1900-01-01pour é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.
Aaron Bertrand
57

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» .

gros nez
la source
3
Votre lien vers "Comment traiter les informations manquantes sans valeurs Nulls" montre bien pourquoi nous ne pouvons pas nous passer des valeurs NULL: Plusieurs suggestions seraient impossibles à mettre en œuvre de manière rationnelle sur les principaux SGBDR actuels.
Jack Douglas
7
Jack: D'accord, mais “les implémentations actuelles ne peuvent pas le faire” n'est pas un argument pour le statu quo :-)
bignose le
17
Est-ce un peu comme dire que nous ne devrions pas voler parce que les avions ne sont pas parfaits?
Aaron Bertrand
11
Non, cela veut dire que les vendeurs devraient cesser de demander des excuses pour les valeurs nulles qui pourraient être valables il y a quarante ans, mais qui ont depuis longtemps dépassé leur délai de conservation raisonnable. Les temps d'E / S ne sont plus dans l'ordre de grandeur de 80 ms. Les cycles d'unité centrale ne sont plus dans l'ordre de grandeur des microsecondes. Les limites de mémoire ne sont plus de l'ordre de quelques meg. Contrairement à il y a quarante ans, les vitesses et capacités matérielles nécessaires pour travailler sans null existent maintenant et le coût n'est pas prohibitif. Il dit qu'il est temps de passer à autre chose.
Erwin Smout
2
Le lien "NULL confusion" est mort.
jpmc26
32

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.

Mark Storey-Smith
la source
2
Je suggère d'avoir un ensemble défini par l'utilisateur de différents types de null, et une logique à valeurs multiples définie par l'utilisateur pour aller avec eux: p
Jack Douglas
13
Ce ne sont pas les seules options. Vous excluez l'alternative de normalisation: au lieu de colonnes qui peuvent ou non avoir une valeur, utilisez une autre table qui peut ou non avoir une ligne correspondante pour la première table. La signification de la présence ou de l'absence d'une ligne est impliquée dans la signification des tableaux, et il n'y a pas de casse spéciale des valeurs NULL ou sentinelles, etc.
bignose
7
La présence de NULL ne nécessite pas de valeurs de casse spéciale ou de sentinelle. Ce ne sont que des symptômes de la façon dont certaines personnes décident de traiter les NULL.
Aaron Bertrand
Il est intéressant de noter que '' est distinct de null sur PostgreSQL (bien que pas Oracle) et vous donne donc un marqueur double, et vous pouvez utiliser 0 pour les colonnes numériques. Le problème avec 0 est que cela ne fonctionne pas pour les clés étrangères.
Chris Travers
13

Permettez-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.

  1. Les valeurs nulles rendent le développement plus difficile et sujet aux bogues.
  2. Les valeurs Null rendent les requêtes, les procédures stockées et les vues plus complexes et sujets aux bogues.
  3. Les valeurs nulles occupent de la place (? Octets basés sur une longueur de colonne fixe ou 2 octets pour une longueur de colonne variable).
  4. Les valeurs nulles peuvent souvent affecter l’indexation et les mathématiques.

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.

Relation Nullable inconnue et tête à tête

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.

Nicholas Aguirre
la source
2
Je voudrais simplement le changer pour qu'il n'y ait pas d' TerminationDateenregistrements d'employés, mais une table pour TerminatedEmployeelaquelle 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 la TerminatedEmployeetable. 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.
Programster
2
Je pourrais littéralement continuer pendant des jours à expliquer pourquoi cela serait mauvais. Tables redondantes, mauvaises pratiques SQL, obligeant ainsi vos développeurs à rechercher à deux endroits différentes les données relatives aux employés, les problèmes de rapport, les problèmes liés aux adresses URI directes d'un employé qui n'existe pas (a été déplacé), et la liste continue et sur. Il est tout à fait bien d'avoir NULLS pour les champs qui auront un jour une valeur, c'est une autre histoire d'avoir des champs qui ne sont jamais remplis et qui n'ont pas d'utilisation. Un certain nombre de problèmes potentiels et de solutions de contournement pour résoudre ce problème ne mériteraient pas le petit problème de la vérification de la valeur NULL sur un champ.
Nicholas Aguirre
1
Je ne suis pas d'accord. La seule chose qui soit redondante est ce champ nul pour la date de fin qui peut ne jamais être rempli. Les développeurs n'ont qu'à rechercher dans la table appropriée les données qu'ils souhaitent et pourraient améliorer les performances. Si, pour une raison quelconque, vous souhaitez que les employés terminés et non terminés soient résolus par une jointure, 90% du temps, votre application voudra probablement l'un ou l'autre. Je pense que la mise en page que j'ai spécifiée est meilleure car il serait impossible d'avoir une date de licenciement pour un employé et pour lui d'avoir encore un compte.
Programster
2
Je n'ai pas parlé de données redondantes, mais de tables redondantes. De plus, toute modification apportée aux tables d'employés doit se répercuter sur les tables terminées. cela rend l'application sujette aux erreurs et rend le travail du développeur beaucoup plus difficile. De plus, un champ de date de fin sera rempli pour presque tout le monde. Il est inutile et problématique de créer une deuxième structure de tableau identique et de déplacer les données. Ne pas inclure les tests à chaque fois pour s'assurer que les données de la table ont été déplacées et nettoyées. Il est déconseillé de supprimer des données d’une table, ne serait-ce que pour les déplacer. Si vous êtes tellement préoccupé par un seul champ que ...
Nicholas Aguirre
1
... qui sera presque toujours rempli à temps, puis créez une table terminée avec une relation 1to1 avec l'employé. Je travaille avec diverses bases de données toute la journée, à la fois en tant que DBA et en tant que développeur, et je suis heureux de ne pas en avoir trouvé une avec la structure que vous avez proposée. Surtout du point de vue du développeur, ce serait un cauchemar d'écrire et de vérifier toutes les erreurs car vous ne sauriez pas de quelle table il s'agit. Même en écrivant une jointure, les données renvoyées au logiciel auraient un champ avec des données nulles, ce qui vous obligerait à le tester également.
Nicholas Aguirre
13

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:

if (b == 0)
  do something when dividing by error
else
  return a / b

Avec NULL, cela devient un peu plus compliqué. Ensemble avec bvous aurez besoin d'un indicateur si best nul et similaire pour a. Le chèque devient maintenant:

if (b_null_bit == NULL)
   return NULL
else if (b == 0) 
   do something when dividing by error
else if (a_null_bit == NULL)
   return NULL
else 
   return a / b

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:

x_vector = a_vector / b_vector
if (fetestexception(FE_DIVBYZERO))
   do something when dividing by zero
return x_vector;

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.

Thomas Kejser
la source
10

Des questions intéressantes.

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 les chaînes).

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.

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.

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.

Chris Travers
la source
10

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.

Derek Downey
la source
-12

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:

select 'IF NOT EXISTS (SELECT 1 FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ' WHERE ' + QUOTENAME(c.name) + ' IS NULL)
    AND (SELECT COUNT(*) FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ') > 1 PRINT ''' + s.name + '.' + t.name + '.' + REPLACE(c.name, '''', '''''') + ''''
    from sys.columns c
    inner join sys.tables t ON c.object_id = t.object_id
    inner join sys.schemas s ON s.schema_id = t.schema_id
    where c.is_nullable = 1 AND c.is_computed = 0
    order by s.name, t.name, c.name;

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.

Matthew Sontum
la source
1
Les commentaires ne sont pas pour une discussion prolongée; cette conversation a été déplacée pour discuter .
Paul White