J'espère ici clarifier ma position.
Cette NULL = NULL
évaluation FALSE
est fausse. Hacker et Mister ont répondu correctement NULL
. Voici pourquoi. Dewayne Christensen m'a écrit, dans un commentaire à Scott Ivey :
Puisque nous sommes en décembre, utilisons un exemple saisonnier. J'ai deux cadeaux sous l'arbre. Maintenant, dites-moi si j'en ai deux de la même chose ou non.
Ils peuvent être différents ou être égaux, vous ne le savez pas tant que l'on n'a pas ouvert les deux cadeaux. Qui sait? Vous avez invité deux personnes qui ne se connaissent pas et qui vous ont fait le même cadeau - rare, mais pas impossible § .
Alors la question: ces deux cadeaux INCONNU sont-ils identiques (égaux, =)? La bonne réponse est: INCONNU (c'est-à-dire NULL
).
Cet exemple visait à démontrer que ".. ( false
ou null
, selon votre système) .." est une réponse correcte - ce n'est pas, seulement NULL
est correcte en 3VL (ou est-ce que vous acceptez un système qui donne de mauvaises réponses? )
Une réponse correcte à cette question doit souligner ces deux points:
- la logique à trois valeurs (3VL) est contre-intuitive (voir d'innombrables autres questions à ce sujet sur Stackoverflow et dans d'autres forums pour vous en assurer);
- Souvent, les SGBD basés sur SQL ne respectent même pas 3VL, ils donnent parfois de mauvaises réponses (comme l'affirme l'affiche d'origine, SQL Server le fait dans ce cas).
Je répète donc: SQL ne sert à rien de forcer à interpréter la propriété réflexive de l'égalité, qui stipule que:
for any x, x = x
§§ (en clair: quel que soit l'univers du discours, une «chose» est toujours égale à elle-même ).
.. dans un 3VL ( TRUE
, FALSE
, NULL
). L'attente des personnes se conformerait à 2VL ( TRUE
, FALSE
qui même dans SQL est valable pour toutes les autres valeurs), à savoir x = x
évaluer toujours TRUE
, pour toute valeur possible de x - sans exception.
Notez également que les NULL sont des " non-valeurs valides" " (comme leurs apologistes le prétendent) que l'on peut attribuer comme valeurs d'attribut (??) dans le cadre des variables de relation. Ce sont donc des valeurs acceptables de chaque type (domaine), pas seulement du type d'expressions logiques.
Et c'était mon point :, NULL
comme valeur, est une "bête étrange". Sans euphémisme, je préfère dire: non - sens .
Je pense que cette formulation est beaucoup plus claire et moins discutable - désolé pour ma faible maîtrise de l'anglais.
C'est seulement l' un des problèmes de NULLs. Mieux vaut les éviter complètement, si possible.
§ nous sommes préoccupés par les valeurs ici, donc le fait que les deux présents soient toujours deux objets physiques différents ne constitue pas une objection valable; si vous n'êtes pas convaincu je suis désolé, ce n'est pas ici le lieu pour expliquer la différence entre la sémantique valeur et "objet" (l'algèbre relationnelle a une sémantique de valeur dès le début - voir le principe d'information de Codd; je pense que certains implémenteurs de SGBD SQL ne ne se soucie même pas d'une sémantique commune).
§§ à ma connaissance, c'est un axiome accepté (sous une forme ou une autre, mais toujours interprété dans un 2VL) depuis l'antiquité et cela précisément parce qu'il est si intuitif. 3VLs (est une famille de logiques en réalité) est un développement beaucoup plus récent (mais je ne sais pas quand a été développé pour la première fois).
Note latérale: si quelqu'un introduit des types de bas , d' unité et d' option comme tentatives de justifier les NULL SQL, je ne serai convaincu qu'après un examen assez détaillé qui montrera comment les implémentations SQL avec des NULL ont un système de type sonore et clarifiera, enfin, ce que sont vraiment les NULL (ces «valeurs pas tout à fait»).
Dans ce qui suit, je citerai quelques auteurs. Toute erreur ou omission est probablement la mienne et non celle des auteurs originaux.
Joe Celko sur les NULL SQL
Je vois Joe Celko souvent cité sur ce forum. Apparemment, c'est un auteur très respecté ici. Alors, je me suis dit: "qu'est-ce qu'il a écrit sur les NULL SQL? Comment explique-t-il les nombreux problèmes des NULL?". Un de mes amis a une version ebook du SQL de Joe Celko pour les smarties: programmation SQL avancée, 3e édition . Voyons voir.
Tout d'abord, la table des matières. Ce qui me frappe le plus, c'est le nombre de fois où NULL est mentionné et dans les contextes les plus variés:
3.4 Arithmétique et valeurs NULL 109
3.5 Conversion de valeurs vers et à partir de NULL 110
3.5.1 Fonction NULLIF () 110
6 NULL: données manquantes dans SQL 185
6.4 Comparaison de NULL 190
6.5 NULL et logique 190
6.5.1 NULLS dans les prédicats de sous-requête 191
6.5.2 Standard Solutions SQL 193
6.6 Mathématiques et NULL 193
6.7 Fonctions et NULL 193
6.8 NULL et langages hôtes 194
6.9 Conseils de conception pour les NULL 195
6.9.1 Éviter les NULL des programmes hôtes 197
6.10 Remarque sur les valeurs NULL multiples 198
10.1 Prédicat IS NULL 241
10.1. 1 Sources des NULL 242
...
etc. Cela me semble un "cas spécial méchant".
J'entrerai dans certains de ces cas avec des extraits de ce livre, en essayant de me limiter à l'essentiel, pour des raisons de copyright. Je pense que ces citations relèvent de la doctrine du «fair use» et qu'elles peuvent même inciter à acheter le livre - j'espère donc que personne ne se plaindra (sinon je devrai en supprimer la plupart, sinon la totalité). De plus, je m'abstiendrai de signaler des extraits de code pour la même raison. Désolé pour ça. Achetez le livre pour en savoir plus sur le raisonnement datailed.
Numéros de page entre parenthèses dans ce qui suit.
Contrainte NOT NULL (11)
La contrainte de colonne la plus importante est NOT NULL, qui interdit l'utilisation de NULL dans une colonne. Utilisez cette contrainte régulièrement et supprimez-la uniquement lorsque vous avez une bonne raison. Cela vous aidera à éviter les complications des valeurs NULL lorsque vous effectuez des requêtes sur les données.
Ce n'est pas une valeur ; c'est un marqueur qui tient une place où une valeur pourrait aller.
Encore une fois, cette "valeur mais pas tout à fait une valeur" absurde. Le reste me paraît tout à fait raisonnable.
(12)
En bref, les NULL provoquent de nombreuses fonctionnalités irrégulières dans SQL, dont nous parlerons plus tard. Votre meilleur pari est simplement de mémoriser les situations et les règles pour les NULL lorsque vous ne pouvez pas les éviter.
À propos de SQL, NULL et infini:
(104) CHAPITRE 3: DONNÉES NUMÉRIQUES EN SQL
SQL n'a pas accepté le modèle IEEE pour les mathématiques pour plusieurs raisons.
...
Si les règles IEEE pour les mathématiques étaient autorisées dans SQL, nous aurions besoin de règles de conversion de type pour infini et d'un moyen de représenter une valeur numérique exacte infinie après la conversion. Les gens ont assez de problèmes avec les NULL, alors n'allons pas là-bas.
Les implémentations SQL sont indécises sur ce que signifie vraiment NULL dans des contextes particuliers:
3.6.2 Fonctions exponentielles (116)
Le problème est que les logarithmes ne sont pas définis lorsque (x <= 0). Certaines implémentations SQL renvoient un message d'erreur, certaines renvoient un NULL et DB2 / 400; la version 3 version 1 a renvoyé * NEGINF (abréviation de «infini négatif») comme résultat.
Joe Celko citant David McGoveran et CJ Date:
6 NULL: données manquantes dans SQL (185)
Dans leur livre A Guide to Sybase and SQL Server , David McGoveran et CJ Date ont déclaré: «C'est l'opinion de cet auteur que les NULL, du moins tels qu'ils sont actuellement définis et implémentés dans SQL, sont bien plus problématiques qu'ils ne valent et doivent être évités; ils affichent un comportement très étrange et incohérent et peuvent être une riche source d'erreur et de confusion. (Veuillez noter que ces commentaires et critiques s'appliquent à tout système prenant en charge les valeurs NULL de style SQL, et pas uniquement à SQL Server en particulier.) »
NULL en tant que toxicomanie :
(186/187)
Dans la suite de ce livre, je vous exhorte à ne pas les utiliser , ce qui peut sembler contradictoire, mais ce n'est pas le cas. Considérez un NULL comme un médicament; utilisez-le correctement et cela fonctionne pour vous, mais abusez-en et cela peut tout gâcher. Votre meilleure politique est d'éviter les valeurs NULL lorsque vous le pouvez et de les utiliser correctement lorsque vous le devez.
Mon unique objection ici est de «les utiliser correctement», ce qui interagit mal avec des comportements d'implémentation spécifiques.
6.5.1 NULLS dans les prédicats de sous-requête (191/192)
Les gens oublient qu'une sous-requête cache souvent une comparaison avec un NULL. Considérez ces deux tableaux:
...
Le résultat sera vide. C'est contre - intuitif , mais correct.
(séparateur)
6.5.2 Solutions SQL standard (193)
SQL-92 a résolu certains des problèmes 3VL (logique à trois valeurs) en ajoutant un nouveau prédicat de la forme:
<condition de recherche> IS [NOT] TRUE | FALSE | INCONNUE
Mais INCONNU est une source de problèmes en soi, de sorte que CJ Date, dans son livre cité ci-dessous, recommande au chapitre 4.5. Éviter les valeurs nulles dans SQL :
- N'utilisez le mot-clé INCONNU dans aucun contexte.
Lisez "ASIDE" sur INCONNU, également lié ci-dessous.
6.8 NULL et langues hôtes (194)
Cependant, vous devez savoir comment les NULL sont gérés lorsqu'ils doivent être passés à un programme hôte. Aucun langage hôte standard pour lequel une intégration est définie ne prend en charge les valeurs NULL, ce qui est une autre bonne raison d'éviter de les utiliser dans votre schéma de base de données.
(séparateur)
6.9 Conseils de conception pour les NULL (195)
C'est une bonne idée de déclarer toutes vos tables de base avec des contraintes NOT NULL sur toutes les colonnes chaque fois que possible. Les NULL confondent les personnes qui ne connaissent pas SQL, et les NULL sont chers.
Objection: NULL confond même les personnes qui connaissent bien SQL, voir ci-dessous.
(195)
Les valeurs NULL doivent être évitées dans les FOREIGN KEY. SQL autorise cette relation «bénéfice du doute», mais il peut entraîner une perte d'informations dans les requêtes impliquant des jointures. Par exemple, étant donné un code de numéro de pièce dans l'inventaire qui est référencé comme une clé étrangère par une table Commandes, vous aurez des problèmes pour obtenir une liste des pièces qui ont un NULL. C'est une relation obligatoire; vous ne pouvez pas commander une pièce qui n'existe pas.
(séparateur)
6.9.1 Éviter les valeurs NULL des programmes hôtes (197)
Vous pouvez éviter de mettre des valeurs NULL dans la base de données à partir des programmes hôtes avec une certaine discipline de programmation.
...
- Déterminez l'impact des données manquantes sur la programmation et la création de rapports: les
colonnes numériques avec NULL posent problème, car les requêtes utilisant des fonctions d'agrégation peuvent fournir des résultats trompeurs.
(séparateur)
(227)
La somme () d'un ensemble vide est toujours NULL. L'une des erreurs de programmation les plus courantes lors de l'utilisation de cette astuce est d'écrire une requête qui pourrait renvoyer plus d'une ligne. Si vous n'y avez pas réfléchi, vous avez peut-être écrit le dernier exemple comme suit: ...
(séparateur)
10.1.1 Sources des NULL (242)
Il est important de se rappeler où les NULL peuvent se produire. Ils sont plus qu'une simple valeur possible dans une colonne . Les fonctions d'agrégation sur des ensembles vides, les jointures externes, les expressions arithmétiques avec des valeurs NULL et les opérateurs OLAP renvoient toutes des valeurs NULL. Ces constructions apparaissent souvent sous forme de colonnes dans les vues.
(séparateur)
(301)
Un autre problème avec les valeurs NULL est détecté lorsque vous essayez de convertir des prédicats IN en prédicats EXISTS.
(séparateur)
16.3 Fonctions de prédicat ALL et Extrema (313)
Il est au début contre-intuitif que ces deux prédicats ne soient pas les mêmes en SQL:
...
Mais vous devez vous rappeler les règles des fonctions extrema - elles suppriment toutes les valeurs NULL avant de renvoyer les valeurs supérieures ou inférieures. Le prédicat ALL ne supprime pas les NULL, vous pouvez donc les obtenir dans les résultats.
(séparateur)
(315)
Cependant, la définition de la norme est rédigée par la négative, de sorte que les NULL bénéficient du doute. ...
Comme vous pouvez le voir, il est judicieux d'éviter les valeurs NULL dans les contraintes UNIQUE.
Discussion GROUPE BY:
Les NULL sont traités comme s'ils étaient tous égaux les uns aux autres et forment leur propre groupe. Chaque groupe est ensuite réduit à une seule ligne dans une nouvelle table de résultats qui remplace l'ancienne.
Cela signifie que pour GROUP BY, la clause NULL = NULL ne s'évalue pas à NULL, comme dans 3VL, mais à TRUE.
Le standard SQL est déroutant:
ORDER BY et NULL (329)
La question de savoir si une valeur de clé de tri qui est NULL est considérée comme supérieure ou inférieure à une valeur non NULL est définie par l'implémentation, mais ...
... Il existe des produits SQL qui le font dans les deux cas.
En mars 1999, Chris Farrar a soulevé une question d'un de ses développeurs qui l'a amené à examiner une partie du standard SQL que je croyais comprendre . Chris a trouvé quelques différences entre la compréhension générale et le libellé réel de la spécification .
Etc. Je pense que c'est assez par Celko.
Date CJ sur les NULL SQL
CJ Date est plus radical sur les NULL: évitez les NULL en SQL, point final. En fait, le chapitre 4 de sa théorie SQL et relationnelle: Comment écrire du code SQL précis est intitulé "PAS DE DUPLICATES, PAS DE NULLS", avec des sous-chapitres
"4.4 Qu'est-ce qui ne va pas avec les Nulls?" et "4.5 Eviter les Nulls en SQL" (suivez le lien: grâce à Google Livres, vous pouvez lire certaines pages en ligne).
Fabian Pascal sur les NULL SQL
De ses problèmes pratiques dans la gestion de base de données - Une référence pour le praticien de la pensée (pas d'extraits en ligne, désolé):
10.3 Implications pratiques
10.3.1 NULL SQL
... SQL souffre des problèmes inhérents à 3VL ainsi que de nombreuses bizarreries, complications, contre-intuitivité et erreurs flagrantes [10, 11]; parmi eux sont les suivants:
- Les fonctions d'agrégation (par exemple, SUM (), AVG ()) ignorent les valeurs NULL (à l'exception de COUNT ()).
- Une expression scalaire sur une table sans lignes est évaluée de manière incorrecte à NULL, au lieu de 0.
- L'expression "NULL = NULL" est évaluée à NULL, mais n'est en fait pas valide en SQL; pourtant ORDER BY traite les NULL comme égaux (tout ce qu'ils précèdent ou suivent les valeurs «régulières» est laissé au fournisseur de SGBD).
- L'expression "x IS NOT NULL" n'est pas égale à "NOT (x IS NULL)", comme c'est le cas dans 2VL.
...
Tous les dialectes SQL mis en œuvre commercialement suivent cette approche 3VL et, par conséquent, non seulement ils présentent ces problèmes, mais ils ont également des problèmes d'implémentation spécifiques, qui varient d'un produit à l'autre .