ユーザーが私のウェブサイトに投稿したすべてのフォーラムメッセージを保存するテーブルがあります。メッセージ階層構造は、入れ子集合モデルを使用して実装されます。
以下は、テーブルの単純化された構造です。
- Id(主キー)
- Owner_Id(IDへの外部キー参照)
- Parent_Id(IDへの外部キー参照)
- nleft
- そろそろ
- nlevel
これで、テーブルは次のようになります。
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
| 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 |
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
最初の行はルートメッセージであり、この投稿のツリーは次のように表示できることに注意してください。
-- SELECT * FROM forumTbl WHERE Owner_Id = 1 ORDER BY nleft;
MESSAGE (Id = 1)
MESSAGE (Id = 2)
Message (Id = 3)
Message (Id = 4)
Owner_Id
1つのクエリで同じ行のすべての行を削除しようとすると、問題が発生します。例:
DELETE FROM forumTbl WHERE Owner_Id = 1 ORDER BY nright;
上記のクエリは次のエラーで失敗します。
エラーコード:1451。親行を削除または更新できません:外部キー制約が失敗しました(
forumTbl
、制約Owner_Id_frgn
外部キー(Owner_Id
)参照forumTbl
(Id
)削除削除アクションなし更新アクションなし
その理由は、ルートノード()である最初の行のフィールド()にも同じ値があり、外部キー制約のためにクエリが失敗するためです。Id=1
Owner_Id
Owner_Id=1
私の質問は次のとおりです。この外部キー制約の循環を回避し、それ自体を参照する行を削除するにはどうすればよいですか ルート行のを最初に更新する必要なしにそれを行う方法はありますか?Owner_Id
NULL
このシナリオのデモを作成しました:http : //sqlfiddle.com/#!9 / fd1b1
ありがとうございました。