Le `NULL` en SQL est étrange
(jirevwe.github.io)-
En SQL, les valeurs
NULLsont traitées de manière particulière. Une colonne avec une contrainteUNIQUEpeut contenir plusieurs valeursNULL.- Cela vient du fait que chaque valeur
NULLest considérée comme une valeur indépendante, différente des autresNULL - SQLite, Postgres et MySQL se comportent tous de la même manière.
- Cela vient du fait que chaque valeur
-
Établir une référence
select '' = ''; -- Returns 1 (true) les chaînes vides sont égales select 1 = 1; -- Returns 1 (true) les nombres sont égaux select 1 = 0; -- Returns 0 (false) les nombres sont différents select null = null; -- Returns NULL (null) Hein ?- Comme
NULLest un espace réservé qui représente une « valeur inconnue », deux valeurs inconnues ne sont pas considérées comme égales - En utilisant l’opérateur
IS, on peut vérifier l’identité deNULL. Par exemple,null is nullrenvoie TRUE.
- Comme
-
À propos de l’unicité
- Quand une colonne avec une contrainte
UNIQUEcontient des valeursNULL, ces valeursNULLsont considérées comme différentes les unes des autres et ne violent donc pas la contrainte d’unicité. - Par exemple,
('ray@mail.com', NULL)et('ray@mail.com', NULL)sont considérées comme deux lignes différentes.
- Quand une colonne avec une contrainte
-
Pourquoi
NULLest traité ainsi- SQLite et les autres bases de données compatibles SQL sont implémentées de cette façon pour gérer
NULLde manière cohérente avec les autres bases de données. La documentation du standard SQL suggère queNULLdevrait être unique partout, mais en pratique la plupart des moteurs SQL ne traitent pasNULLcomme unique dansSELECT DISTINCTouUNION.
- SQLite et les autres bases de données compatibles SQL sont implémentées de cette façon pour gérer
-
Comment garantir l’unicité
-
Utiliser une colonne générée
- On peut atténuer le problème en créant une colonne qui a toujours une valeur déterministe non nulle. Par exemple, on peut remplacer les valeurs
NULLavecCOALESCE(deleted_at, '1970-01-01'). - Cette méthode peut occuper de l’espace en ajoutant un champ supplémentaire à la table.
- On peut atténuer le problème en créant une colonne qui a toujours une valeur déterministe non nulle. Par exemple, on peut remplacer les valeurs
-
Utiliser un index partiel
- On peut garantir l’unicité en créant un index partiel sur
emailuniquement lorsquedeleted_atvautNULL. - Un index partiel élargit moins la table, prend moins d’espace et ne produit pas d’erreur lorsqu’on supprime de manière répétée la même paire d’enregistrements.
- On peut garantir l’unicité en créant un index partiel sur
-
-
Mise à jour
- Oracle traite les chaînes vides comme
NULL.
- Oracle traite les chaînes vides comme
-
Conclusion
- C’est invisible lorsqu’on utilise un ORM, mais la façon particulière dont SQL traite
NULLpeut être source de confusion. La documentation du standard SQL n’est pas disponible publiquement et n’est accessible que contre paiement.
- C’est invisible lorsqu’on utilise un ORM, mais la façon particulière dont SQL traite
2 commentaires
Tous les
nullsont étranges.Du coup, le
nulltout à fait normal de SQL finit plutôt par paraître étrange…Au royaume des borgnes, celui qui a deux yeux est anormal…
Commentaires Hacker News
Le
NULLde SQL repose sur la logique TRUE-FALSE-UNKNOWN de Kleene. Si l’on litNULLcomme UNKNOWN, de nombreuses opérations deviennent plus intuitives à comprendreNULLest un espace réservé représentant UNKNOWN, et on ne peut pas dire que deuxNULLsont égauxNULLS NOT DISTINCTLorsque le concept de
NULLa été introduit dans les années 1970, on pensait déjà qu’il provoquerait beaucoup de confusion à l’avenir. Quarante-cinq ans plus tard, le sujet fait toujours débatCompréhension intuitive de
NULL: une valeurNULLdans une cellule d’une table est une manière d’indiquer « pas de valeur ». Lorsqu’on veut des valeurs uniques, les cas où il n’y a pas de valeur ne devraient pas être pris en compteScepticisme vis-à-vis de l’utilisation des ORM : les ORM sont pratiques, mais ils ont produit une génération qui n’a pas appris le fonctionnement réel des bases de données relationnelles. Le comportement de
SQL NULLest cohérent avec l’algèbre relationnelle de base, et c’est leNULLde style C qui pose problèmeCela rappelle l’humour d’une réplique d’un épisode de Blackadder sur la comparaison de
NULLLe fait qu’Oracle considère
NULLcomme égal à une chaîne vide semble étrangeDans un contexte orienté objet, "null" est utile pour indiquer qu’une propriété donnée n’a pas de valeur. En JavaScript, il y a
nulletundefined; on peut considérer queundefinedsignifie que la valeur est inconnue, tandis quenullsignifie qu’il n’y a pas de valeurNULLn’est pas étrange au sens où il n’implique pas de doublons. Comme lesNULLne sont pas égaux entre eux, ils ne peuvent pas constituer des doublons. Si l’on n’aime pas la sémantique deNULL, on peut utiliser une valeur sentinelleLe
NULLde SQL n’est pas étrange si l’on réfléchit à la manière dont la logique relationnelle devrait fonctionner dans des enregistrements contenant des valeurs inexistantes