Je sais que ce sujet est un peu controversé et que de nombreux articles / opinions circulent sur Internet. Malheureusement, la plupart d'entre eux supposent que la personne ne sait pas quelle est la différence entre NULL et une chaîne vide. Donc, ils racontent des histoires sur des résultats surprenants avec des jointures / agrégats et font généralement des leçons SQL un peu plus avancées. En faisant cela, ils manquent absolument tout et sont donc inutiles pour moi. J'espère donc que cette question et toutes les réponses avancent un peu.
Supposons que j'ai une table avec des informations personnelles (nom, naissance, etc.) où l'une des colonnes est une adresse email de type varchar. Nous supposons que pour une raison quelconque, certaines personnes pourraient ne pas vouloir fournir une adresse électronique. Lorsque vous insérez ces données (sans courrier électronique) dans la table, vous avez le choix entre deux options: définissez la cellule sur NULL ou définissez-la sur une chaîne vide (''). Supposons que je connaisse toutes les implications techniques du choix d’une solution sur une autre et que je puisse créer des requêtes SQL correctes pour l’un ou l’autre des scénarios. Le problème est que même lorsque les deux valeurs diffèrent sur le plan technique, elles sont exactement les mêmes sur le plan logique. Après avoir regardé NULL et '' je suis arrivé à une conclusion: je ne connais pas l'adresse électronique du gars. Aussi peu importe combien j'ai essayé, Je ne pouvais pas envoyer de courrier électronique en utilisant la chaîne NULL ou une chaîne vide. La plupart des serveurs SMTP étaient apparemment en accord avec ma logique. J'ai donc tendance à utiliser NULL où je ne connais pas la valeur et considère la chaîne vide comme une mauvaise chose.
Après des discussions intenses avec des collègues, je suis venu avec deux questions:
Ai-je raison de supposer que l'utilisation d'une chaîne vide pour une valeur inconnue provoque le "mensonge" d'une base de données sur les faits? Pour être plus précis: en utilisant l'idée de SQL sur ce qui est valeur et ce qui ne l'est pas, je pourrais arriver à la conclusion suivante: nous avons une adresse électronique, simplement en découvrant qu'elle n'est pas nulle. Mais plus tard, lorsque j'essayerai d'envoyer un courrier électronique, je parviendrai à une conclusion contradictoire: non, nous n'avons pas d'adresse de courrier électronique, cette @! # $ Base de données a dû mentir!
Existe-t-il un scénario logique dans lequel une chaîne vide '' pourrait être un si bon porteur d'informations importantes (sans valeur ni valeur), qu'il serait gênant / inefficace de stocker par tout autre moyen (comme une colonne supplémentaire). J'ai vu de nombreux articles affirmant qu'il est parfois utile d'utiliser des chaînes vides avec des valeurs réelles et des valeurs NULL, mais jusqu'à présent, je n'ai pas vu de scénario qui serait logique (en termes de conception SQL / DB).
PS Certaines personnes seront tentées de répondre que c'est simplement une question de goût personnel. Je ne suis pas d'accord Pour moi, c'est une décision de conception avec des conséquences importantes. Je voudrais donc voir des réponses où l'opinion à ce sujet est soutenue par des raisons logiques et / ou techniques.
''
même dans Oracle, ce n'est pas la même chose queNULL
. Par exemple, l’affectation d’uneCHAR(1)
colonne à la valeur (c’est-''
à' '
-dire un espace), pasNULL
. En outre, si Jacek utilisait Oracle, cette question ne serait probablement pas posée :-)'' IS NULL
évaluétrue
en PL / SQL.Réponses:
Je dirais que
NULL
c'est le bon choix pour "pas d'adresse email". Il existe de nombreuses adresses e-mail "non valides" et "" (chaîne vide) n'en est qu'une. Par exemple, "foo" n'est pas une adresse électronique valide, "a @ b @ c" n'est pas valide, etc. Donc, juste parce que "" n’est pas une adresse email valide, il n’ya aucune raison de l’utiliser comme valeur "pas d’adresse email".Je pense que vous avez raison de dire que "" n’est pas la bonne façon de dire "je n’ai pas de valeur pour cette colonne". "" est une valeur.
Un exemple où "" pourrait être une valeur valide, séparée de
NULL
pourrait être le deuxième prénom d'une personne. Tous n’ont pas un deuxième prénom, vous devez donc différencier "sans prénom" ("" - chaîne vide) de "je ne sais pas si cette personne a un deuxième prénom ou non" (NULL
). Il existe probablement de nombreux autres exemples dans lesquels une chaîne vide est toujours une valeur valide pour une colonne.la source
NULL
cela ne signifie pas qu’il n’ya pas d’adresse électronique, je pense que cela signifie que l’adresse électronique est actuellement inconnue, inconnue ou impossible à remplir pour d’autres raisons. Heureusement, il n’ya probablement pas de situation où l’on voudrait conserver dans une base de données les informations sur les personnes qui n’ont vraiment pas et ne prévoient pas d’adresse électronique, sinon un champ booléen séparé serait probablement nécessaire.Tout en souscrivant aux commentaires ci-dessus, j’ajouterais cet argument comme principale motivation:
Par souci de codage intuitif auto-documenté, utilisez NULL au lieu de chaînes vides.
la source
Dans votre exemple, si la valeur provient directement du champ Web, j'utiliserais une chaîne vide. Si l'utilisateur peut choisir de ne pas fournir d'e-mail ou de le supprimer, alors NULL.
Voici un lien avec des points que vous pourriez considérer: https://stackoverflow.com/questions/405909/null-vs-empty-when-dealing-with-user-input/405945#405945
--- édité (En réponse au commentaire de Thomas) ---
Les bases de données ne vivent pas sans applications qui les utilisent. Définir NULL ou '' n'a pas de valeur, si l'application ne peut pas l'utiliser correctement.
Prenons un exemple où l'utilisateur remplit le formulaire LONG et appuie sur Entrée pour envoyer la demande persistante au serveur. Il pourrait être en train d'entrer son email. Très probablement, vous voulez stocker tout ce qu'il a dans le champ email, pour qu'il puisse le finir plus tard. Et s'il n'entrait qu'un seul personnage? Et s’il entrait dans un caractère et le supprimait ensuite? Lorsque le courrier électronique n'est pas requis, les utilisateurs souhaitent parfois le supprimer: le moyen le plus simple d'effacer le champ. De même, dans le cas où un courrier électronique n'est pas nécessaire, il convient de le valider avant de l'envoyer.
Autre exemple: l'utilisateur fournit un courrier électronique en tant que spamto @ [bigcompany] .com - dans ce cas, il n'est pas nécessaire d'envoyer un courrier électronique, même s'il est existant et valide (et peut même exister). L'envoi d'un tel message est peut-être bon marché, mais s'il y a 10 000 utilisateurs avec de tels courriers électroniques pour les abonnements quotidiens, cette validation peut vous faire gagner beaucoup de temps.
la source
Je pense que Dean Hardings répond vraiment bien à cela. Cela dit, j'aimerais mentionner que lorsque vous parlez de valeurs NULL par rapport à des chaînes vides au niveau de la base de données, vous devez réfléchir à vos autres types de données. Voulez-vous stocker date min quand aucune date n'est fournie? ou -1 quand aucun int n'est fourni? Le fait de stocker une valeur sans valeur signifie que vous devez alors suivre toute une gamme de non-valeurs. Au moins un pour chaque type de données (éventuellement plus si vous obtenez des cas où -1 est une valeur réelle, vous devez donc avoir une alternative, etc.). Si vous avez besoin de faire quelque chose de "flou" au niveau de l’application, c’est une chose, mais il n’est pas nécessaire de polluer vos données.
la source
Malheureusement, Oracle a confondu la représentation de la chaîne VARCHAR de longueur zéro avec la représentation de NULL. Ils sont tous deux représentés en interne par un seul octet de valeur zéro. Cela rend la discussion encore plus difficile.
Une grande partie de la confusion entourant NULL est centrée sur une logique à trois valeurs . Considérons le pseudocode suivant:
Vous ne vous attendriez pas au troisième message, mais c'est ce que vous obtiendriez sous une logique à trois valeurs. La logique à trois valeurs conduit les gens vers de nombreux bugs.
Une autre source de confusion est de tirer des conclusions de l’absence de données, comme de tirer des conclusions du chien qui n’a pas aboyé la nuit. Souvent, ces déductions n'étaient pas ce que l'auteur du NULL avait l'intention de cnvey.
Cela dit, il existe de nombreuses situations dans lesquelles NULL gère parfaitement l’absence de données et produit exactement le résultat souhaité. Un exemple est les clés étrangères dans les relations facultatives. Si vous utilisez une valeur NULL pour n'indiquer aucune relation dans une ligne donnée, cette ligne sera supprimée d'une jointure interne, comme vous le souhaitiez.
Sachez également que même si vous évitez complètement NULLS dans les données stockées (sixième forme normale), si vous effectuez des jointures externes, vous devrez tout de même vous en servir.
la source
Utilisez Null.
Il ne sert à rien de stocker une valeur de '', il vous suffira de rendre le champ de la table nullable. Cela rend les requêtes plus évidentes aussi.
Quelle requête SQL est plus évidente et lisible si vous voulez trouver des utilisateurs avec une adresse email?
SELECT * FROM Users WHERE email_address != ''
SELECT * FROM Users WHERE email_address IS NOT NULL
SELECT * FROM Users WHERE email_address != '' and email_address IS NOT NULL
Je dirais que 2 est. Bien que 3 soit plus robuste dans les cas où de mauvaises données sont stockées.
Pour le cas de l'adresse e-mail sur le formulaire, qui est facultative, elle devrait également être reflétée dans le tableau. En SQL, il s'agit d'un champ nullable, ce qui signifie qu'il n'est pas connu.
Je ne vois aucune valeur commerciale raisonnable pour stocker une chaîne vide dans une table autre que simplement un mauvais design. C'est comme si vous stockiez une valeur de chaîne 'NULL' ou 'BLANK', et que les développeurs supposent qu'elle est nulle ou vide. Pour moi, c'est un mauvais design. Pourquoi stocker ça quand il y a NULL ??
Utilisez simplement NULL, et vous rendrez un peu plus heureux tout le monde.
PLUS D'INFORMATIONS:
SQL utilise un système logique à trois valeurs: True, False et Unknown.
Pour une explication meilleure et plus détaillée, je recommande aux développeurs de lire: Requêtes SQL - au-delà de VRAI et FAUX .
la source
pour la question technique spécifique, le problème n'est pas null vs chaîne vide, c'est un échec de validation . Une chaîne vide n'est pas une adresse email valide!
pour la question philosophique, la réponse est similaire: validez vos entrées. Si une chaîne vide est une valeur valide pour le champ en question, attendez-la et codez-la; sinon, utilisez null.
Une chaîne vide serait une entrée valide pour répondre à la question: Qu'est-ce que le mime a dit à la girafe?
la source
Je pourrais penser à une raison pour avoir NULL et la chaîne vide:
[email protected]
NULL
Empty String.
Cependant, je ne le recommanderais pas et utiliserais un champ séparé pour demander si vous savez s'il n'en existe aucun.
la source
Si je comprends bien, la question est de savoir quelles interprétations de NULL et de chaîne vide doivent être choisies. Cela dépend du nombre d' états dans lesquels le champ particulier peut être situé.
L'interprétation dépend de la manière dont la base de données est utilisée. S'il existe une couche dans le code qui extrait complètement la base de données, le choix d'une stratégie (y compris deux règles) qui fonctionne est tout à fait acceptable. (Il est toutefois important de documenter la politique.) Cependant, si la base de données est utilisée à plusieurs endroits, vous devez utiliser un schéma très simple, car le code sera plus difficile à gérer et peut être erroné dans ce cas.
la source
Fondamentalement, sur le plan logique, il n'y a pas de différence entre la valeur "invalide" et "aucune entrée d'utilisateur", il s'agit simplement de "cas particuliers" la plupart du temps. Cas d'erreur.
Avoir la valeur null prend un espace supplémentaire: ceil (columns_with_null / 8) en octets / par ligne.
Cellule vide et null sont les deux moyens de marquer que quelque chose ne va pas / devrait être par défaut. Pourquoi auriez-vous besoin de 2 "mauvais" états? Pourquoi utiliser des valeurs NULL si elles occupent davantage d’espace et ont exactement la même signification que des chaînes vides? Cela introduira simplement de la confusion et de la redondance lorsque vous rencontrez deux choses qui signifient (cela pourrait signifier) exactement la même chose, il est facile d’oublier que vous devez utiliser des valeurs NULL au lieu de chaînes vides (si, par exemple, un utilisateur a omis certains champs).
Et vos données peuvent devenir un gâchis. Dans un monde parfait, vous diriez "les données seront toujours correctes et je m'en souviendrai" ... mais quand les gens doivent travailler en équipe et que tout le monde n’est pas à votre niveau, il n’est pas rare de voir WHERE (aa. xx <> '' AND bb.zz N'EST PAS NUL)
Donc, au lieu de corriger les membres de mon équipe tous les deux jours, je m’applique simplement à la règle. Aucune valeur nulle, JAMAIS!
Compter les valeurs NON NULL est plus rapide ... une question simple est de savoir pourquoi vous auriez besoin de faire cela.
la source
VARCHAR
colonne prendra au moins 1 octet pour stocker la longueur de la chaîne, même si elle est nulle.J'ai tendance à le voir non pas du point de vue de la base de données, mais du point de vue du programme. Je sais que cette question concerne le clic SQL, mais combien d'utilisateurs ont directement accès aux données?
Dans un programme, je n'aime pas null / rien. Il y a quelques exceptions, mais ce n'est que cela. Et ces exceptions ne sont que de mauvaises implémentations.
Donc, si l'utilisateur n'a pas mis le courrier électronique, il devrait y avoir quelque chose qui détermine si cela est valide ou non. Si un e-mail vierge convient, une chaîne vide apparaît. Si l'utilisateur n'a pas mis de courrier électronique et que cela enfreint une règle, l'objet doit l'indiquer.
L'idée de donner un sens à zéro est vieille école et est quelque chose que les programmeurs modernes doivent contourner.
Même dans une conception de base de données, pourquoi le champ de courrier électronique ne permet-il pas d'autoriser les valeurs NULL, d'avoir une chaîne de longueur nulle et d'avoir un autre champ indiquant si l'utilisateur a saisi quelque chose? Est-ce un peu cela demander à un SGBD? À mon avis, la base de données ne devrait gérer ni la logique d’entreprise ni la logique d’affichage. Il n'a pas été construit pour cela et fait donc très mal son travail.
la source
Je ne pense pas que cela compte beaucoup, mais je l’aime mieux lorsque la valeur NULL est présente.
Lorsque je visualise les données affichées dans une table (comme dans SQL Server Management Studio), je peux mieux distinguer une valeur manquante si elle indique NULL et que l'arrière-plan est de couleur différente.
Si je vois un espace vide, je me demande toujours s'il est vraiment vide ou s'il y a des espaces blancs ou des personnages invisibles. Avec NULL, la garantie est vide à première vue.
Je ne distingue généralement pas les valeurs dans l'application, car il est inattendu et étrange que NULL et une chaîne vide signifient quelque chose de différent. Et la plupart du temps, je prends une approche défensive et ne fais que traiter avec les deux États. Mais pour moi en tant qu'être humain, NULL est plus facile à traiter lorsque vous examinez les données.
la source