Eu tenho uma tabela na qual guardo todas as mensagens do fórum postadas pelos usuários no meu site. A estrutura da hierarquia de mensagens é implementada usando um modelo de conjunto aninhado .
A seguir, é apresentada uma estrutura simplificada da tabela:
- ID (CHAVE PRIMÁRIA)
- Owner_Id (REFERÊNCIAS DA CHAVE ESTRANGEIRA AO ID )
- Parent_Id (REFERÊNCIAS DA CHAVE ESTRANGEIRA AO ID )
- nleft
- certo
- nlevel
Agora, a tabela está parecida com esta:
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
| 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 |
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
Observe que a primeira linha é a mensagem raiz e a árvore desta postagem pode ser exibida como:
-- SELECT * FROM forumTbl WHERE Owner_Id = 1 ORDER BY nleft;
MESSAGE (Id = 1)
MESSAGE (Id = 2)
Message (Id = 3)
Message (Id = 4)
Meu problema ocorre quando tento excluir todas as linhas da mesma Owner_Id
em uma única consulta. Exemplo:
DELETE FROM forumTbl WHERE Owner_Id = 1 ORDER BY nright;
A consulta acima falha com o seguinte erro:
Código de erro: 1451. Não é possível excluir ou atualizar uma linha pai: uma restrição de chave estrangeira falha (
forumTbl
, CONSTRAINTOwner_Id_frgn
FOREIGN KEY (Owner_Id
) REFERÊNCIASforumTbl
(Id
) EM EXCLUIR SEM AÇÃO NA ATUALIZAÇÃO SEM AÇÃO)
O motivo é que a primeira linha , que é o nó raiz ( Id=1
), também possui o mesmo valor em seu Owner_Id
campo ( Owner_Id=1
) e causa falha na consulta devido à restrição de chave estrangeira.
Minha pergunta é: Como posso evitar essa circularidade de restrição de chave estrangeira e excluir uma linha que faça referência a si mesma? Existe uma maneira de fazer isso sem primeiro precisar atualizar o Owner_Id
da linha raiz NULL
?
Criei uma demonstração desse cenário: http://sqlfiddle.com/#!9/fd1b1
Obrigado.