web-dev-qa-db-fra.com

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

J'ai lu un article sur BBC. L'un des exemples, selon eux, est que les personnes portant le nom de famille "Null" ont du mal à saisir leurs coordonnées sur certains sites Web.

Aucune explication n'est donnée sur l'erreur qu'ils rencontrent.

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?

73
Nitish

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. À l'origine du problème, de nombreux logiciels liés aux bases de données affichent un enregistrement NULL sous la forme de la 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 insensibles à la casse), une telle application considérera tout "null" chaîne doit être NULL. Par conséquent, un nom Null serait considéré comme n'existant pas par cette demande.

La solution consiste à déclarer des colonnes non nulles comme NOT NULL dans la base de données et pour ne pas appliquer d'opérations de chaîne aux enregistrements de la base de données. La plupart des langues ont d'excellentes API de base de données qui rendent inutiles les interfaces au niveau des chaînes. Ils doivent toujours être préférés, car ils rendent moins probables d'autres erreurs telles que l'injection SQL.

103
amon

Pour répondre à votre question spécifique, il existe de nombreuses étapes le long de la chaîne d'événements entre un formulaire Web et la base de données. Si le nom de famille Null est interprété à tort comme une valeur NULL, le système peut rejeter un nom parfaitement valide comme étant non valide. Cela peut se produire au niveau de la couche de base de données comme expliqué par amon . Soit dit en passant, si c'est le problème spécifique, la base de données est également probablement ouverte à l'injection SQL AKA de l'attaque Bobby Tables . --- Une autre étape de la chaîne qui pourrait causer des problèmes est le processus de sérialisation .

Dans l'ensemble, l'article portait sur un problème plus important. Le monde est un grand endroit en désordre qui n'est pas toujours conforme à 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 codent nos données correctement . C'est à l'entreprise de décider combien de ressources nous consacrons à la prise en charge des cas Edge de plus en plus complexes. Bien que je soutienne pleinement 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.

13
Erik

Eh bien, avant qu'il ne soit 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 dans la bibliothèque JSON backend que vous utilisez, 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 faites tout à l'envers. Cela fait beaucoup d'endroits où les programmeurs peuvent faire des erreurs, et généralement beaucoup sans l'avantage de la frappe statique.

7
Karl Bielefeldt

J'attribuerais le problème à une programmation bâclée 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 se glisser dans le paradigme "n'importe quoi fera" et d'accepter des choses considérées comme une chaîne sous une forme non citée.

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

2
ddyer

C'est très probablement un problème de programmation. Si vous regardez cette réponse ici sur la façon dont les valeurs NULL sont transmises, vous pourriez facilement provoquer un comportement indésirable si vous étiez "M. 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 ont été passés en tant que NULL, les données seraient interpolées en tant que null de base de données dans la base de données.

"NULL"! = Base de données Null

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

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

Un autre cas est supposons que le nom de famille était nullable dans la base de données. Mr. 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 base de données.

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

2
Jon Raynor

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

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

Alors que le contexte peut parfois suffire pour distinguer ces concepts, il y a des moments où il ne le fait pas vraiment. Si l'on utilise un enregistrement pour contenir une requête de recherche, par exemple, il devrait y avoir une différence entre dire "Je veux quelqu'un par le nom de [n'importe quoi], sans nom de famille", et "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 ont un parti pris dans un sens ou dans l'autre, mais ils ne sont pas tous les mêmes. Le code qui attend qu'un moteur de base de données fonctionne dans un sens peut mal fonctionner s'il est exécuté sur un moteur différent qui s'exécute différemment.

0
supercat

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 dans SQL:

Si vous êtes invité à 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, cela apparaîtra pour vérifier si u.lastname IS NOT NULL: tous les enregistrements NULL sont filtrés. Tous les enregistrements autres que NULL restent.

Sauf bien sûr pour les enregistrements où u.lastname == 'NULL', mais aucun enregistrement de ce type n'a pu être 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-NULL - ness avec des paramètres, et quelqu'un remarque "hé, si je passez la chaîne NULL, elle fait exactement ce que je veux! "

0
hvd