Pourquoi ne pas utiliser le nombre Nullable dans Oracle?

12

Notre société est en interface avec une autre société de logiciels pour un projet commun, et on nous a dit que, si une valeur particulière ne devait pas être affichée, nous devrions passer un -5000 (leur valeur sentinelle arbitraire); la raison en est qu'aucune colonne numérique de leur base de données Oracle ne prend en charge les valeurs nulles, sur la recommandation de leur (désormais ancien) développeur Oracle. Cette société écrit également la grande majorité de leur code en VB6 (transition lente vers VB.NET, qui est un autre sujet pour un autre jour ...). Par pure curiosité, y a-t-il une raison valable pour cette recommandation? Je ne peux penser à aucun de mon côté.

--- Éditer

Merci pour tous les commentaires. J'ai posé la même question sur CodeProject.com ( lien ) et j'ai reçu des commentaires très similaires. Il semble que la seule fois où l'on pourrait commencer à justifier cette pratique est liée aux clés étrangères, et je peux affirmer qu'elles n'utilisent aucune clé étrangère n'importe où dans le système. Le développeur qui a fait cette détermination (j'avais l'habitude de travailler dans cette entreprise) a beaucoup plus d'expérience que moi, donc je voulais m'assurer qu'il n'y avait pas de raison valable à cela avant que la dérision ne s'ensuit.

Cade Roux
la source
2
Vous voulez dire, à part "c'est ce que leur API spécifie"?
Robert Harvey
Oui, je suis plus curieux de savoir pourquoi leur API spécifierait cela en premier lieu; y a-t-il une raison à cette pratique, ou est-ce juste une folie?
3
Une folie de premier ordre!
Philᵀᴹ

Réponses:

17

De façon réaliste, l'exigence est folle. Comme toutes les grandes idées folles, cependant, elle est probablement basée sur une pépite de caractère raisonnable potentiel prise loin de son contexte par des gens qui n'ont aucune compréhension de la logique sous-jacente.

Il peut être raisonnable de concevoir un schéma de base de données de sorte qu'aucune NULLvaleur ne soit autorisée. Si vous le faites, cependant, vous vous engagez à un niveau de normalisation où chaque élément non requis est divisé en une table distincte avec une référence de clé étrangère appropriée renvoyée au parent. Ce n'est pas souvent fait dans la pratique, mais dans les cas où cela a du sens, il peut y avoir des avantages.

Si vous envisagez de concevoir un schéma de base de données de telle sorte qu'aucune NULLvaleur ne soit autorisée, cela n'a aucun sens d'autoriser encore moins d'exiger des valeurs magiques pour indiquer que quelque chose est inconnu. Cela introduit tous les problèmes liés à l'autorisation des NULLvaleurs et ajoute du code supplémentaire pour vérifier les valeurs magiques qui doivent être répétées partout. Cela n'a aucun sens de développer une API qui nécessite que des valeurs magiques soient transmises quelle que soit la conception de la base de données.Si vous allez entraver votre code en vérifiant les valeurs magiques, vous ne devriez vraiment pas laisser cette folie se propager à d'autres systèmes .

Justin Cave
la source
+1 et le code supplémentaire pour vérifier les valeurs magiques ne peuvent pas utiliser des fonctions bien connues comme COALESCE()- donc cela devient encore plus compliqué.
ypercubeᵀᴹ
Et les valeurs doivent être stockées dans n'importe quel index de cette colonne. Les index n'ont pas besoin de stocker des valeurs nulles.
Tripp Kinetics
15

Il n'y a aucune raison valable d'utiliser une valeur magique au lieu de NULL. Cela pourrait être le processus de réflexion de quelqu'un qui crée ce gâchis. Ils écrivent quelque chose comme ceci:

 SELECT c1, c2 FROM t1 WHERE c3 < 30;

Lorsque cela ne retourne pas les résultats attendus, ils se rendent compte que cela n'inclut pas les valeurs NULL et devraient écrire ceci:

SELECT c1, c2 FROM t1 WHERE c3 < 30 OR c3 IS NULL;

Ils ne veulent pas écrire ou oublier à l'avenir d'écrire ceci, alors ils trouvent la solution de faire tous les NULLS -5000. Par magie, leur requête d'origine gère les valeurs NULL sans aucune modification. Ce qu'ils ne réalisent pas, c'est que maintenant quelqu'un qui veut exclure ces valeurs doit écrire ceci:

SELECT c1, c2 FROM t1 WHERE c3 < 30 AND c3 <> -5000;

Ou s'ils voulaient ces valeurs et recherchent une gamme plus élevée:

SELECT c1, c2 FROM t1 WHERE c3 > 40 OR c3 = -5000;

Ils peuvent également ne pas réaliser que les éléments suivants n'auraient plus de sens:

SELECT c1, c2 FROM t1 WHERE c3 IS NULL;

Au lieu de cela, une personne doit se souvenir de la valeur magique. Avec chaque type de données utilisé, ils doivent se souvenir de plus de valeurs magiques, par exemple 1/1 // 1900, "Z", -5000. De plus, lorsque la valeur magique est dans les données, ils doivent également se souvenir de valeurs magiques alternatives.

Ainsi, pour un cas spécifique, cela simplifie le code au détriment d'autres cas, sans parler de l'espace disque, de la taille de l'index, de l'analyse des requêtes, de la cohérence, etc.

Leigh Riffel
la source
8

C'est une folie totale et il n'y a aucune justification à cela. NULLa été créé pour représenter l'absence de valeur et pour utiliser une valeur réelle telle que -5000 is bonkers.

Normalement, je n'écrirais pas une réponse aussi courte, mais la question mérite d'être l'une des plus visibles sur dba.se et plus il y a de réponses, mieux c'est.

Philᵀᴹ
la source
5

J'ai réfléchi un peu à cela en essayant d'être positif et en justifiant la nécessité d'utiliser une valeur arbitraire au lieu d'une valeur nulle et il ne semble (au moins) pas y avoir de raison valable, sauf peut-être dans un ensemble de données d'exploration de données fermé pour améliorer et simplifier les performances et les requêtes, puis uniquement dans les cas où les nombres ne sont pas des valeurs susceptibles de fausser les données. Même cela devrait être examiné attentivement. Dans toutes les situations réelles, attribuer une valeur à null n'est pas une bonne pratique. Cela transforme une définition de colonne NOT NULL de votre ami à votre ennemi car ce n'est vraiment pas vrai.

C'est une chose très différente de dire que notre application ne doit pas accepter une valeur NULL pour certaines (ou même toutes) les colonnes. C'est une pratique judicieuse et bonne et il y a des avantages bien documentés à ne pas autoriser les valeurs nulles (clés et index et calculs statistiques par exemple). Cependant, assigner une valeur à "s'asseoir à la place" d'un null n'est pas du tout la même. C'est la tige pour votre propre dos, car vous devez d'abord sélectionner une valeur qui ne sera jamais utilisée, filtrer cette valeur comme vous le feriez et ne pas oublier de ne pas l'utiliser dans les calculs et les résumés et de la supprimer des flux de données externes . C'est au moins aussi mauvais d'utiliser un null pour représenter une valeur réelle, ce que vous vous dites que vous évitez, mais vous ne l'êtes pas.

La plupart des problèmes causés par les valeurs nulles, une fois compris, peuvent être traités (meilleure normalisation, index fonctionnels ou bitmap ou avec un simple WHERE x IS NOT NULL). Pensez-vous que dans une grande entreprise de télécommunications ou sur Amazon lors de la réunion mensuelle sur les performances, certains administrateurs de base de données décrivent ce grand plan pour accélérer un peu les requêtes sur leurs énormes ensembles de données "en remplaçant null par une valeur arbitraire, quelque chose comme -5000, ou autre - Je suis ouvert sur la valeur ... ". Ou pensez-vous qu'ils passent leur temps partagé entre une meilleure conception d'application pour filtrer les valeurs nulles indésirables et l'optimisation des requêtes en fonction des données réelles qui leur sont fournies ? OK, peut-être qu'une réunion mensuelle est un peu optimiste, mais chaque fois que cela se produit, je peux vous assurer que "Remplacer les valeurs nulles par -5000 (ou autre) pour une meilleure API" n'est pas un point de l'ordre du jour.

Pour moi, c'est bien de dire que je n'accepterai pas de données manquantes (vous devez avoir un âge ou un prix ou un code de région ou autre) et parfois même bien de dire que pour cette colonne il y a une valeur par défaut qui sera entrée si vous ne mettez pas autre chose. Il n'est pas bien de mettre de côté une valeur pour signifier nulle. Considérez les champs du deuxième prénom comme exemple. Parfois, ceux-ci n'existeront pas car les parents sont trop paresseux pour remplir toutes les cases. Ajoutons-nous "aucun" ou "manquant" ou "inconnu" à nos données pour améliorer nos recherches? Non, car il peut y avoir des personnes étranges qui changent leurs noms en ces valeurs et donc lorsque nous imprimons les données, nous ne savons pas si nous devons les inclure ou non. Il s'agit d'un exemple simple mais d'une grande portée. Nous connaissons NULL et avons des fonctions intégrées prévisibles pour y faire face. Vous ne pouvez pas mieux coder cela.

Si aucune réponse (ou NULL) n'est pas une réponse valide à votre demande d'entrée, ne l'autorisez pas dans l'application ou dans la base de données, si c'est une bonne réponse, vous devez l'autoriser dans votre application et votre base de données et gérer comme une réponse valide. S'il fait partie d'un ensemble de réponses valides, votre base de données doit être conçue pour le stocker. Après tout, vous ne dites pas bon, les champs numériques sont si ennuyeux que de stocker des nombres dans des blobs et d'utiliser des photos d'animaux sauvages pour représenter chaque nombre, parce que c'est fou (cool mais fou). Nous ne décidons pas non plus que nous n'aimons pas la lettre B, et comme un cauchemar cruel de Sesame Street, remplacez-le par un # dans nos données. Si B n'est pas une réponse que nous voulons, nous disons à l'utilisateur "Hé, vous ne pouvez pas mettre un B ici". Alors pourquoi traiter null différemment?

Évitez donc les valeurs nulles que vous ne voulez pas au niveau de l'application et traitez-les dans votre base de données où vous les acceptez autrement, aussi sûr que girafe + giraffe = hippo, votre manipulation de données inutile vous causera des ennuis.


la source
2
Mes parents n'étaient pas paresseux et je n'ai d'ailleurs aucun deuxième prénom. Les gens ne vivent pas tous aux États-Unis.
ypercubeᵀᴹ
1
C'était censé être un exemple léger, aucune infraction ne signifiait. Il y a, bien sûr, beaucoup de gens sans prénoms (le premier point) pour de nombreuses raisons tout à fait valables (le point principal). Null dans cette colonne ne vous explique pas pourquoi il manquait. Je ne suis pas sûr de votre angle géopolitique - je ne vis pas aux États-Unis mais j'ai en fait un deuxième prénom. Il est difficile de faire des hypothèses sur la base de données manquantes, je suppose.
Aucune infraction prise. J'ai voté votre réponse en fait. Je pense que vous avez touché le clou avec votre argument principal qu'il y a une différence entre ne pas accepter / autoriser Nulls dans la base de données et remplacer Nulls par une valeur magique.
ypercubeᵀᴹ
5
J'adorerais si mon deuxième prénom était "-5000"! : D
Philᵀᴹ