Ho una tabella in cui memorizzo tutti i messaggi del forum pubblicati dagli utenti sul mio sito Web. La gerarchia dei messaggi strucrue viene implementata utilizzando un modello di set nidificato .
Di seguito è riportata una struttura semplificata della tabella:
- Id (CHIAVE PRIMARIA)
- Owner_Id (RIFERIMENTI CHIAVE ESTERI A ID )
- Parent_Id (RIFERIMENTI CHIAVE ESTERI A ID )
- Nleft
- Nright
- nLevel
Ora, la tabella è simile a questa:
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
| 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 |
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
Si noti che la prima riga è il messaggio principale e l'albero di questo post può essere visualizzato come:
-- SELECT * FROM forumTbl WHERE Owner_Id = 1 ORDER BY nleft;
MESSAGE (Id = 1)
MESSAGE (Id = 2)
Message (Id = 3)
Message (Id = 4)
Il mio problema si verifica quando provo a eliminare tutte le righe sotto lo stesso Owner_Id
in una singola query. Esempio:
DELETE FROM forumTbl WHERE Owner_Id = 1 ORDER BY nright;
La query precedente non riesce con il seguente errore:
Codice errore: 1451. Impossibile eliminare o aggiornare una riga principale: un vincolo di chiave esterna non riesce (
forumTbl
, RIFERIMENTIOwner_Id_frgn
CHIAVE ESTERA VINCOLI (Owner_Id
)forumTbl
(Id
) ON ELIMINA NO AZIONE ON AGGIORNAMENTO NO AZIONE)
Il motivo è che la prima riga , che è il nodo principale ( Id=1
), ha anche lo stesso valore nel suo Owner_Id
campo ( Owner_Id=1
) e causa l'interruzione della query a causa del vincolo della chiave esterna.
La mia domanda è: come posso evitare la circolarità di questo vincolo di chiave esterna ed eliminare una riga che fa riferimento a se stessa? C'è un modo per farlo senza prima dover aggiornare il file Owner_Id
della riga principale NULL
?
Ho creato una demo di questo scenario: http://sqlfiddle.com/#!9/fd1b1
Grazie.