Tenho uma tabela na qual armazeno todas as mensagens do fórum postadas pelos usuários no meu site. A estrutura de hierarquia de mensagens é implementada usando um modelo de conjunto aninhado .
A seguir, uma estrutura simplificada da tabela:
- ID (CHAVE PRIMÁRIA)
- Owner_Id (REFERÊNCIAS DE CHAVE ESTRANGEIRA PARA Id )
- Parent_Id (REFERÊNCIAS DE CHAVE ESTRANGEIRA PARA Id )
- esquerda
- certo
- nível
Agora, a tabela está mais ou menos assim:
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
| 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 deste post 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 sob o mesmo 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
) REFERENCESforumTbl
(Id
) ON DELETE NO ACTION ON UPDATE NO ACTION)
O motivo é que a primeira linha , que é o nó raiz ( Id=1
), também tem o mesmo valor em seu Owner_Id
campo ( Owner_Id=1
), e isso faz com que a consulta falhe devido à restrição de chave estrangeira.
Minha pergunta é: Como posso evitar essa circularidade de restrição de chave estrangeira e excluir uma linha que faz referência a si mesma? Existe uma maneira de fazer isso sem primeiro ter que atualizar o Owner_Id
da linha raiz para NULL
?
Eu criei uma demonstração deste cenário: http://sqlfiddle.com/#!9/fd1b1
Obrigada.