I have a table in which I store all the forum messages posted by the users on my website. The messages hierarchy strucrue is implement using a Nested set model.
The following is a simplified structure of the table:
- Id (PRIMARY KEY)
- Owner_Id (FOREIGN KEY REFERENCES TO Id)
- Parent_Id (FOREIGN KEY REFERENCES TO Id)
- nleft
- nright
- nlevel
Now, the table is looking something like this:
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
| 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 |
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
Note that the first row is the root message, and the tree of this post can be displayed as:
-- SELECT * FROM forumTbl WHERE Owner_Id = 1 ORDER BY nleft;
MESSAGE (Id = 1)
MESSAGE (Id = 2)
Message (Id = 3)
Message (Id = 4)
My problem occurs when I try to delete all the rows under the same Owner_Id
in a single query. Example:
DELETE FROM forumTbl WHERE Owner_Id = 1 ORDER BY nright;
The above query fails with the following error:
Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails (
forumTbl
, CONSTRAINTOwner_Id_frgn
FOREIGN KEY (Owner_Id
) REFERENCESforumTbl
(Id
) ON DELETE NO ACTION ON UPDATE NO ACTION)
The reason is that the first row, which is the root node (Id=1
), also has the same value in its Owner_Id
field (Owner_Id=1
), and it causing the query to fail due to the foreign key constraint.
My question is: How can I prevent this foreign key constraint circularity and delete a row that reference to itself? Is there a way to do it without first having to update the the Owner_Id
of the root row to NULL
?
I created a demo of this scenario: http://sqlfiddle.com/#!9/fd1b1
Thank you.