76 votes

Utilisation standard de 'Z' au lieu de NULL pour représenter les données manquantes ?

En dehors de la question de savoir si les NULL doivent être utilisés ou non : Je suis responsable d'une base de données existante qui utilise NULL pour signifier "données manquantes ou jamais saisies". C'est différent de la chaîne vide, qui signifie "un utilisateur a défini cette valeur, et il a choisi 'vide'".

Un autre contractant du projet est fermement convaincu que les NULL n'existent pas pour moi, que je ne les utilise jamais et que personne d'autre ne devrait le faire. Cependant, ce qui me trouble, c'est que, puisque l'équipe du contractant reconnaît la différence entre "manquant/non saisi" et "intentionnellement vide ou indiqué par l'utilisateur comme inconnu", elle utilise un seul caractère "Z" dans tout son code et ses procédures stockées pour représenter "manquant/non saisi" avec la même signification que NULL dans le reste de la base de données.

Bien que notre client commun ait demandé que cela soit modifié et que j'aie appuyé cette demande, l'équipe considère qu'il s'agit d'une "pratique standard" parmi les DBA beaucoup plus avancés que moi ; ils sont réticents à changer pour utiliser les NULL sur la base de ma seule demande ignorante. Alors, quelqu'un peut-il m'aider à surmonter mon ignorance ? Existe-t-il une norme, un petit groupe d'individus, ou même une seule voix forte parmi les experts SQL qui préconise l'utilisation de 'Z' à la place de NULL ?

Mise à jour

J'ai une réponse de l'entrepreneur à ajouter. Voici ce qu'il a dit lorsque le client a demandé à ce que les valeurs spéciales soient supprimées pour permettre les NULL dans les colonnes sans données :

En fait, j'ai conçu la base de données pour éviter les NULLs dans la mesure du possible. Voici le raisonnement :

- Un NULL dans un champ [VARCHAR] de type chaîne n'est jamais nécessaire car une chaîne vide (de longueur nulle) fournit exactement les mêmes informations.

- Un NULL dans un champ entier (par exemple, une valeur d'identification) peut être traité en utilisant une valeur qui n'apparaîtrait jamais dans les données (par exemple, -1 pour un champ entier d'IDENTITÉ).

- Un NULL dans un champ de date peut facilement entraîner des complications dans les calculs de date. Par exemple, dans la logique qui calcule les différences de date, comme la différence en jours entre une [RecoveryDate] et une [OnsetDate], la logique va exploser si l'une ou les deux dates sont NULL - à moins qu'une tolérance explicite ne soit faite pour que les deux dates soient NULL. C'est un travail supplémentaire et une manipulation supplémentaire. Si des dates "par défaut" ou "fictives" sont utilisées pour [RecoveryDate] et [OnsetDate] (par exemple, "1/1/1900"), les calculs mathématiques peuvent donner des valeurs "inhabituelles", mais la logique des dates ne sera pas perturbée.

La gestion des NULL est traditionnellement un domaine où les développeurs font des erreurs dans les procédures stockées.

Au cours de mes 15 années d'expérience en tant que DBA, j'ai constaté qu'il était préférable d'éviter les NULL dans la mesure du possible.

Cela semble valider la réaction majoritairement négative à cette question. Au lieu d'appliquer une approche 6NF acceptée pour concevoir l'élimination des NULL, des valeurs spéciales sont utilisées pour "éviter les NULL dans la mesure du possible". J'ai posé cette question avec un esprit ouvert, et je suis heureux d'en avoir appris davantage sur le débat "les NULL sont utiles / les NULL sont diaboliques", mais je suis maintenant assez à l'aise pour qualifier l'approche des "valeurs spéciales" de non-sens total.

une chaîne vide (de longueur nulle) fournit exactement la même information.

Non, ce n'est pas le cas ; dans la base de données existante que nous modifions, NULL signifie "jamais saisi" et chaîne vide signifie "saisi comme vide".

La gestion des NULL est traditionnellement un domaine où les développeurs font des erreurs dans les procédures stockées.

Oui, mais ces erreurs ont été commises des milliers de fois par des milliers de développeurs, et les leçons et mises en garde pour éviter ces erreurs sont connues et documentées. Comme cela a été mentionné ici : que vous acceptiez ou rejetiez les NULLs, la représentation des valeurs manquantes est un problème de sécurité. problème résolu . Il n'est pas nécessaire d'inventer une nouvelle solution simplement parce que les développeurs continuent à faire des erreurs faciles à surmonter (et à identifier).


En guise de note de bas de page : je suis un DBE et un développeur depuis plus de 20 ans (ce qui est certainement suffisant pour que je connaisse la différence entre un ingénieur de base de données et un administrateur de base de données). Tout au long de ma carrière, j'ai toujours été dans le camp des "NULLs are useful", même si je savais que plusieurs personnes très intelligentes n'étaient pas d'accord. J'étais extrêmement sceptique quant à l'approche des "valeurs spéciales", mais je n'étais pas assez bien informé sur "How To Avoid NULL the Right Way" pour prendre une position ferme. J'aime toujours apprendre de nouvelles choses - et j'ai encore beaucoup à apprendre après 20 ans. Merci à tous ceux qui ont contribué à rendre cette discussion utile.

104voto

MatBailie Points 37610

Virez votre entrepreneur.

Ok, sérieusement, ce n'est pas une pratique courante. Cela peut être vu simplement parce que tous les SGBDR avec lesquels j'ai travaillé implémentent NULL, la logique pour NULL, prennent en compte NULL dans les clés étrangères, ont un comportement différent pour NULL dans COUNT, etc, etc.

Je dirais même que l'utilisation de "Z" ou de tout autre substitut est pire. Vous avez toujours besoin d'un code pour vérifier la présence de "Z". Mais vous devez également documenter le fait que "Z" ne signifie pas "Z", mais quelque chose d'autre. Et vous devez vous assurer que cette documentation est lue. Et que se passe-t-il si "Z" devient un jour une donnée valide ? (Par exemple, un champ pour une initiale ?)

À un niveau de base, même sans débattre de la validité de NULL contre 'Z', j'insisterais pour que le contractant se conforme aux pratiques standard qui existent au sein de votre entreprise, et non de la sienne. L'introduction de sa pratique standard dans un environnement où il existe une autre pratique standard entraînera une confusion, des frais généraux de maintenance, des malentendus et, au final, une augmentation des coûts et des erreurs.


EDIT

Il y a des cas où l'utilisation d'une alternative à NULL est valable à mon avis. Mais seulement lorsque cela permet de réduire le code, plutôt que de créer des cas particuliers dont il faut tenir compte.

Je l'ai utilisé pour les données liées à une date, par exemple. Si les données sont valides entre une date de début et une date de fin, le code peut être simplifié en n'ayant pas de valeurs NULL. Une date de début NULL peut être remplacée par '01 Jan 1900' et une date de fin NULL peut être remplacée par '31 Dec 2079'.

Cela peut encore modifier le comportement par rapport à ce qui est attendu, et doit donc être utilisé avec précaution :

  • WHERE end-date IS NULL ne donnent plus de données qui sont encore valables
  • Vous venez de créer votre propre bogue du millénaire
  • etc.

Cela revient à réformer les abstractions de telle sorte que toutes les propriétés puissent toujours avoir des valeurs valides. C'est très différent de l'encodage implicite d'une signification spécifique dans des valeurs choisies arbitrairement.

Quand même, virez l'entrepreneur.

26voto

Mark Mann Points 2872

C'est facilement l'une des opinions les plus bizarres que j'ai jamais entendues. Utiliser une valeur magique pour représenter "aucune donnée" plutôt que NULL signifie que chaque morceau de code que vous avez devra post-traiter les résultats pour tenir compte des valeurs "no-data"/"Z".

NULL est spécial en raison de la manière dont la base de données le traite dans les requêtes. Par exemple, prenez ces deux requêtes simples :

select * from mytable where name = 'bob';
select * from mytable where name != 'bob';

Si name est toujours NULL, il n'apparaîtra évidemment pas dans les résultats de la première requête. Plus important encore, il n'apparaîtra pas non plus dans les résultats de la seconde requête. NULL ne correspond à rien d'autre qu'une recherche explicite de NULL, comme dans :

select * from mytable where name is NULL;

Et que se passe-t-il lorsque les données pourraient avoir Z comme valeur valide ? Disons que vous stockez l'initiale du second prénom de quelqu'un ? Zachary Z Zonkas serait-il mis dans le même panier que les personnes qui n'ont pas de deuxième initiale ? Ou bien votre prestataire devra-t-il trouver une autre valeur magique pour gérer cette situation ?

Évitez les valeurs magiques qui vous obligent à implémenter des fonctionnalités de la base de données dans un code que la base de données est déjà parfaitement capable de gérer. Il s'agit d'un problème résolu et bien compris, et il se peut que votre contractant n'ait jamais vraiment compris la notion de NULL et évite donc de l'utiliser.

22voto

Mitch Wheat Points 169614

Si le domaine autorise les valeurs manquantes, l'utilisation de NULL pour représenter "indéfini" est parfaitement acceptable (c'est pour cela qu'il est là). Le seul inconvénient est que le code qui consomme les données doit être écrit pour vérifier les NULL. C'est ainsi que j'ai toujours procédé.

Je n'ai jamais entendu parler (ou vu dans la pratique) de l'utilisation de "Z" pour représenter les données manquantes. Quant à "l'entrepreneur cite cela comme une "pratique standard" parmi les DBA", peut-il fournir des preuves de cette affirmation ? Comme @Dems l'a mentionné, vous devez également documenter le fait que 'Z' ne signifie pas 'Z' : que diriez-vous d'un MiddleInitial colonne ?

Comme Aaron Alton et bien d'autres, je pense que les valeurs NULL font partie intégrante de la conception des bases de données et qu'elles doivent être utilisées lorsque cela est approprié.

17voto

WW. Points 11335

Même si vous parvenez à expliquer à tous vos développeurs et DBA actuels et futurs l'existence de "Z" au lieu de NULL, et même s'ils codent tout à la perfection, vous confondrez toujours l'optimiseur car il ne saura pas que vous avez inventé cela.

L'utilisation d'une valeur spéciale pour représenter NULL (qui est déjà une valeur spéciale pour représenter NULL) entraînera des distorsions dans les données. Par exemple, il s'est passé tellement de choses le 1er janvier 1900 que l'optimiseur ne pourra pas comprendre la plage réelle de dates qui est vraiment pertinente pour votre application.

C'est comme si un manager décidait : "Porter une cravate est mauvais pour la productivité, alors nous allons tous porter du ruban adhésif autour du cou. Problème résolu."

9voto

stakx Points 29832

Je n'ai jamais entendu parler de l'utilisation répandue de 'Z' en remplacement de NULL .

(Soit dit en passant, je n'aimerais pas particulièrement travailler avec un contractant qui vous dit en face qu'il et d'autres DBA "avancés" sont tellement plus compétents et meilleurs que vous).

 +=================================+
 |  FavoriteLetters                |
 +=================================+
 |  Person      |  FavoriteLetter  |
 +--------------+------------------+
 |  'Anna'      |  'A'             |
 |  'Bob'       |  'B'             |
 |  'Claire'    |  'C'             |
 |  'Zaphod'    |  'Z'             |
 +---------------------------------+

Comment votre entrepreneur interpréterait-il les données de la dernière ligne ?

Il choisira probablement une autre "valeur magique" dans ce tableau pour éviter toute collision avec les données réelles. 'Z' ? Cela signifie que vous devez vous souvenir de plusieurs valeurs magiques et de celle qui est utilisée à tel ou tel endroit... En quoi est-ce mieux que d'avoir un seul jeton magique ? NULL et de devoir se souvenir des règles (et des pièges) de la logique à trois valeurs qui l'accompagnent ? NULL est au moins standardisée, contrairement à celle de votre entrepreneur. 'Z' .

Je n'aime pas particulièrement NULL soit, mais en le substituant inconsidérément par une valeur réelle (ou pire, par plusieurs valeurs réelles) partout est presque certainement pire que NULL .

Permettez-moi de répéter ici mon commentaire ci-dessus pour une meilleure visibilité : Si vous voulez lire quelque chose de sérieux et de bien fondé de la part de personnes qui sont contre NULL Je vous recommande l'article suivant "Comment gérer les informations manquantes sans utiliser les NULLs" (liens vers un PDF de Page d'accueil du troisième manifeste ).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X