J'ai un tableau dans lequel je stocke tous les messages du forum publiés par les utilisateurs sur mon site Web. La structure de hiérarchie des messages est implémentée à l'aide d'un modèle d'ensemble imbriqué .
Voici une structure simplifiée du tableau:
- Id (CLÉ PRIMAIRE)
- Owner_Id (RÉFÉRENCES CLÉS ÉTRANGÈRES À Id )
- Parent_Id (RÉFÉRENCES DE CLÉS ÉTRANGÈRES À Id )
- nleft
- bien
- nlevel
Maintenant, la table ressemble à ceci:
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
| Id | Owner_Id | Parent_Id | nleft | nright | nlevel |
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
| 1 | 1 | NULL | 1 | 8 | 1 |
| 2 | 1 | 1 | 2 | 5 | 2 |
| 3 | 1 | 2 | 3 | 4 | 3 |
| 4 | 1 | 1 | 6 | 7 | 2 |
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
Notez que la première ligne est le message racine, et l'arborescence de ce message peut être affichée comme:
-- SELECT * FROM forumTbl WHERE Owner_Id = 1 ORDER BY nleft;
MESSAGE (Id = 1)
MESSAGE (Id = 2)
Message (Id = 3)
Message (Id = 4)
Mon problème se produit lorsque j'essaie de supprimer toutes les lignes sous le même Owner_Id
dans une seule requête. Exemple:
DELETE FROM forumTbl WHERE Owner_Id = 1 ORDER BY nright;
La requête ci-dessus échoue avec l'erreur suivante:
Code d'erreur: 1451. Impossible de supprimer ou de mettre à jour une ligne parent: une contrainte de clé étrangère échoue (
forumTbl
, CONSTRAINTOwner_Id_frgn
FOREIGN KEY (Owner_Id
) REFERENCESforumTbl
(Id
) ON DELETE NO ACTION ON UPDATE NO ACTION)
La raison en est que la première ligne , qui est le nœud racine ( Id=1
), a également la même valeur dans son Owner_Id
champ ( Owner_Id=1
), ce qui entraîne l'échec de la requête en raison de la contrainte de clé étrangère.
Ma question est: comment puis-je empêcher cette circularité de la contrainte de clé étrangère et supprimer une ligne qui fait référence à elle-même? Existe-t-il un moyen de le faire sans avoir à mettre à jour au préalable Owner_Id
la ligne racine de NULL
?
J'ai créé une démo de ce scénario: http://sqlfiddle.com/#!9/fd1b1
Je vous remercie.
la source