Maison  >  Article  >  base de données  >  Explication détaillée des contraintes uniques et NULL dans MySQL

Explication détaillée des contraintes uniques et NULL dans MySQL

黄舟
黄舟original
2017-05-21 10:10:231231parcourir

Ce qui est enregistré ici est un bug qui s'est produit il y a longtemps. Il vous présente principalement les informations pertinentes sur la contrainte d'unicité et NULL dans MySQL. Dans l'article L'introduction est très détaillée et a une certaine valeur de référence et d'apprentissage pour tous les amis qui en ont besoin peuvent y jeter un œil ci-dessous.

Préface

Une exigence que j'ai faite auparavant, une description simplifiée consiste à accepter les messages MQ d'autres groupes, puis à insérer un enregistrement dans le base de données . Afin de les empêcher d'envoyer des messages répétés et d'insérer plusieurs enregistrements en double, un

index unique a été ajouté à plusieurs colonnes du tableau.

CREATE UNIQUE INDEX IDX_UN_LOAN_PLAN_APP ON testTable (A, B, C);
À l'heure actuelle, les trois colonnes A, B et C n'autorisent pas les valeurs NULL et la contrainte d'unicité fonctionne également.


Plus tard, en raison de changements dans les exigences, la contrainte d'unicité précédente a été modifiée et une colonne supplémentaire a été ajoutée. (Je n'entrerai pas dans les détails sur pourquoi.)

ALTER TABLE testTable
DROP INDEX IDX_UN_LOAN_PLAN_APP,
ADD UNIQUE KEY `IDX_UN_LOAN_PLAN_APP` (A, B, C, D);
Le D nouvellement ajouté est de type

dateheure, qui peut être NULL et la valeur par défaut est NULL. La raison pour laquelle la valeur par défaut est NULL est que tous les enregistrements n'ont pas cette heure. Si vous définissez de force une valeur magique (telle que « 1970-01-01 08:00:00 ») comme valeur par défaut, cela semblera étrange.

Reine bleue. . . Quelque chose s'est mal passé. Après avoir ajouté D, la contrainte d’unicité est fondamentalement invalide.

Insert into testTable (A,B,C,D) VALUES (1,2,3,NULL); --- OK
Insert into testTable (A,B,C,D) VALUES (1,2,3,NULL); --- OK
Insert into testTable (A,B,C,D) VALUES (1,2,3,NULL); --- OK
Les trois SQL ci-dessus peuvent tous être exécutés avec succès et il y aura plusieurs enregistrements identiques dans la base de données. Selon notre idée précédente, l'exception 'Clé en double' devrait être levée lors de l'exécution des deux derniers SQL.

Après l'avoir vérifié, j'ai découvert que le document officiel de MySQL l'indiquait clairement. L'index unique permet l'existence de plusieurs valeurs NULL :

A UNIQUE index creates a constraint such that all values in the index must be distinct. An error occurs if you try to add a new row 
with a key value that matches an existing row. For all engines, a UNIQUE index allows multiple NULL values for columns that can contain NULL.
D'après le tableau ci-dessous, cela peut également être le cas. Il convient de noter que quel que soit le type de moteur de stockage utilisé, plusieurs NULL sont autorisés à exister lors de la création d'une clé unique. . . .


Si vous y réfléchissez, c'est en fait tout à fait raisonnable. Après tout, NULL est considéré comme représentant "inconnu" dans MySQL. En SQL, toute comparaison avec NULL renvoie NULL au lieu de TRUE, même une comparaison entre NULL et NULL renvoie NULL.

Nous ne pouvons donc que le réparer. . . La solution est assez simple et grossière. Actualisez simplement les données en ligne, définissez "1970-01-01 08:00:00" comme valeur par défaut, puis modifiez cette colonne pour ne pas autoriser NULL, hum.

De nombreuses personnes ont discuté de ce problème sur le site officiel de MySQL. Certaines personnes pensent qu'il s'agit d'un bug de MySQL, tandis que d'autres pensent qu'il s'agit d'une fonctionnalité. Un lien est joint.

Bogues MySQL : #8173 : l'index unique autorise les doublons avec des valeurs nulles

Résumé

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn