Comment un nom de famille de Null pose-t-il des problèmes dans de nombreuses bases de données?


71

J'ai lu un article sur la BBC. L'un des exemples cités est que les personnes portant le nom de famille 'Null' rencontrent des difficultés pour entrer leurs coordonnées sur certains sites Web.

Aucune explication n'est donnée sur l'erreur à laquelle ils sont confrontés.

Mais pour autant que je sache, la chaîne 'Null' et la valeur Null réelle sont complètement différentes (du point de vue de la base de données).

Pourquoi cela causerait-il des problèmes dans une base de données?


2
Ceci est un article de blog assez célèbre au sujet des hypothèses que les programmeurs font sur les noms, écrit par l' une des personnes citées dans cet article de la BBC: kalzumeus.com/2010/06/17/...
Jörg W Mittag



4
La première fois que j'ai vu ce type à la télévision, j'ai supposé qu'il s'agissait d'un bug dans la base de données. Puis j'ai découvert que c'était en fait son nom.
Nate Eldredge

3
@JarrodRoberson Comment pouvez-vous affirmer que "la prémisse est fausse", au vu de la description des problèmes rencontrés par "Jennifer Null" et de noms similaires dans le lien affiché par le PO? C'est un véritable problème auquel sont confrontés les vrais utilisateurs finaux.
Gort the Robot

Réponses:


102

Cela ne cause pas de problèmes de base de données. Cela provoque des problèmes dans les applications écrites par des développeurs qui ne comprennent pas les bases de données. À la racine du problème, beaucoup de logiciels liés à la base de données affichent un enregistrement NULL en tant que chaîne NULL. Lorsqu'une application s'appuie ensuite sur la forme de chaîne d'un enregistrement NULL (probablement en utilisant également des opérations de comparaison ne respectant pas la casse), cette application considérera alors toute "null"chaîne comme étant NULL. Par conséquent, un nom Null serait considéré comme n’existant pas par cette application.

La solution consiste à déclarer des colonnes non NULL comme NOT NULLdans la base de données et à ne pas appliquer d'opérations de chaîne aux enregistrements de base de données. La plupart des langues ont d'excellentes API de base de données qui rendent inutiles les interfaces de niveau chaîne. Il faut toujours les préférer, également parce qu’ils font moins d’erreurs telles que l’injection SQL.


30
Dans ce cas, cependant, si vous lisez l'article en question, créer un champ de nom de famille NOT NULLcausera toute une série de problèmes à d'autres personnes. "Certaines personnes n'ont qu'un seul nom, pas un prénom et un nom de famille."
MikeTheLiar

41
@Darkhogg Beaucoup de gens ne sont pas d'accord avec moi à ce sujet, mais je pense que les noms sont comme des adresses électroniques. Ne vous fatiguez pas à les valider, donnez à l'utilisateur une zone de texte unique et laissez-le mettre ce qu'il veut. C’est une information que si j’en ai vraiment besoin, je l’obtiendrai d’une manière certaine.
MikeTheLiar

8
@mikeTheLiar Je ne connais pas le nom de cela, mais il existe toute une classe d'erreurs résultant de la création de règles trop restrictives sur les données. Vous verrez souvent des codes postaux et des numéros de téléphone définis comme numériques dans les applications et les bases de données. Ce ne sont pas vraiment des nombres parce que cela n'a aucun sens de faire des opérations mathématiques sur eux. Ainsi, lorsque quelqu'un tente d'entrer une adresse canadienne, il est bloqué.
JimmyJames

19
@ JimmyJames ouais, les codes postaux stockés sous forme de chiffres et tout à coup, toute personne vivant ici a un code postal en base 8. "Si vous ne faites pas de math avec ça, c'est une chaîne, Full Stop."
MikeTheLiar

8
@mikeTheLiar. Le problème de traiter les noms comme une seule chaîne (généralement préférable, je suis d’accord), c’est qu’il est nécessaire de trier les noms par ordre alphabétique.
TRiG

13

Pour répondre à votre question spécifique, il existe de nombreuses étapes dans la chaîne d'événements entre un formulaire Web et la base de données. Si le nom de famille Nullest interprété à tort comme une NULLvaleur, le système peut rejeter un nom parfaitement valide comme non valide. Cela peut se produire au niveau de la couche de base de données, comme expliqué par amon . Incidemment, s’il s’agit là d’un problème spécifique, la base de données est également susceptible de subir une injection SQL AKA de l’ attaque de Bobby Tables . Le processus de sérialisation est une autre étape de la chaîne qui pourrait poser problème .

Globalement, l'article portait sur un problème plus important. Le monde est un grand endroit en désordre qui ne se conforme pas toujours à nos hypothèses. Cela est particulièrement évident lorsque vous essayez d’internationaliser votre application. À la fin de la journée, nous devons nous assurer que nos applications gèrent et encodent nos données correctement . Il appartient à l’entreprise de décider du nombre de ressources que nous consacrons à la prise en charge de cas critiques toujours plus complexes. Même si je suis entièrement favorable à l'inclusion, je comprendrai si l'entreprise décide que "l'artiste officiellement appelé Prince" doit utiliser un caractère Unicode pour représenter son nom dans notre base de données.


Il est difficile d’imaginer que cela soit dû au type d’interpolation de chaîne non sécurisée pouvant conduire à une injection SQL. Si vous oubliez de citer l'entrée de l'utilisateur dans une requête SQL (par exemple, INSERT INTO users (first, last) VALUES($first, $last)à INSERT INTO users (first, last) VALUES(Jennifer, Null)), toutes les personnes dont les noms ne sont pas des mots clés SQL ou des noms de colonne valides vont simplement générer des erreurs sans que leurs enregistrements ne soient insérés. La cause doit être plus complexe.
Andrew Medico

@ AndrewMedico dans votre exemple d'homme de paille, oui, mais il y a beaucoup de façons de mal faire les choses. Ne sous-estimez jamais le pouvoir de <strike> la stupidité <\ strike> l’ignorance. En fin de compte, nous ne savons absolument pas quel est le problème, car nous ne pouvons pas examiner le code en question
Erik

7

Avant d’être entré dans la base de données, c’est un élément DOM, puis une variable javascript transmise, validée et manipulée, puis une valeur JSON, puis une variable de la bibliothèque JSON principale utilisée, puis une variable transmise, validé et manipulé dans votre langage de programmation backend, puis un élément d’une sorte de DAO, puis une partie d’une chaîne SQL. Ensuite, pour récupérer la valeur, vous procédez en sens inverse. Les programmeurs ont beaucoup d'occasions de faire des erreurs, souvent sans l'avantage du typage statique.


2

Très probablement, c'est un problème de programmation. Si vous regardez cette réponse ici sur la façon dont les valeurs NULL sont passées, vous pourriez facilement provoquer un comportement indésirable si vous étiez "Mr. Null".

https://stackoverflow.com/questions/4620391/mysql-and-php-insert-null-rather-than-empty-string

Vous pouvez voir que si certains éléments de données étaient passés en tant que NULL, les données seraient interpolées en tant que base de données null dans la base de données.

"NULL"! = Base de données Null

Quelques cas d'utilisation et comportements associés ...

Supposons que le nom de famille a été marqué dans la base de données comme non nul. Désormais, lorsque les données sont insérées, elles seront interprétées comme des valeurs NULL et l'échec de l'insertion.

Un autre cas est, disons, que le nom de famille était nul dans la base de données. M. NULL est inséré et est transformé en DBNull.Value qui n'est pas la même chose que "NULL". Après l'insertion, nous ne pouvons pas trouver M. Null car son nom de famille n'est pas "NULL" mais en réalité une valeur nulle de la base de données.

Donc, ce serait 2 cas de problèmes. Comme @Amon le fait remarquer, les bases de données elles-mêmes ne posent aucun problème avec les valeurs NULL, bien qu'il faille comprendre comment les valeurs NULL sont gérées dans chaque instance RDMS car il y aura des différences entre différents fournisseurs.


"Vous pouvez voir que si certains éléments de données étaient passés à NULL, les données seraient interpolées en tant que base de données null dans la base de données." - la question liée SO / réponse acceptée ne semble pas montrer cela?
MrWhite

2

J'attribuerais le problème à une mauvaise programmation et à une mauvaise conception de certaines implémentations de SQL. "Null" le nom doit toujours être présenté et interprété avec des guillemets. null, la valeur de la base de données, doit toujours être présenté sans guillemets; mais lors de l'écriture de code ad-hoc, il est facile de glisser dans le paradigme du "tout fera" et d'accepter des choses considérées comme une chaîne sous une forme non citée.

Cela est aggravé par le fait que d’autres types de données; les nombres, par exemple, peuvent et sont acceptés sous l'une ou l'autre forme parce que l'interprétation est sans ambiguïté.


Vous voulez dire de mauvaises implémentations d' applications utilisant SQL, sûrement? Aucune implémentation sérieuse d'un SGBDR en elle-même ne serait vulnérable à cette situation (comme aucune application sérieuse!)
underscore_d

0

Un problème, fondamentalement, est que le terme "null" est appliqué à deux concepts de base de données différents, en utilisant parfois un contexte pour les distinguer:

  1. Quelque chose n'a pas de valeur connue
  2. Quelque chose est connu pour n'avoir aucune valeur

Bien que le contexte puisse parfois suffire à faire la distinction entre ces concepts, il arrive que ce ne soit pas le cas. Par exemple, si une personne utilise un enregistrement pour effectuer une recherche, il devrait y avoir une différence entre dire "je veux quelqu'un du nom de [peu importe]], sans nom de famille", par opposition à "je veux quelqu'un dont le prénom est [ peu importe] mais dont le nom de famille est inconnu. " De nombreux moteurs de base de données privilégient l'un ou l'autre sens, mais ils ne sont pas tous identiques. Le code qui s'attend à ce qu'un moteur de base de données fonctionne dans un sens peut ne pas fonctionner correctement s'il est exécuté sur un moteur différent qui s'exécute différemment.


Si une chaîne n'a pas de valeur, elle doit être une chaîne vide et non une chaîne nulle.
Byron Jones

0

La plupart des réponses existantes se concentrent sur les parties non SQL d'une application, mais il peut également y avoir un problème en SQL:

Si le système vous demande de filtrer les enregistrements pour lesquels le nom de famille d'un utilisateur n'est pas disponible, une personne qui ne comprend pas très bien SQL peut écrire un filtre WHERE u.lastname != 'NULL'. En raison du fonctionnement de SQL, ceci apparaît pour vérifier si u.lastname IS NOT NULL: tous les NULLenregistrements sont filtrés. Tous les non- NULLenregistrements restent.

Sauf bien sûr pour les enregistrements où u.lastname == 'NULL', mais il se peut qu'aucun enregistrement de ce type ne soit disponible pendant les tests.

Cela devient plus probable si le SQL est généré par une sorte de framework, où ce framework n'expose pas un moyen facilement accessible de vérifier la non- NULLnudité avec des paramètres, et que quelqu'un remarque "hé, si je passe dans la chaîne NULL, ça fait exactement ce que je veux! "

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.