外部キー制約を使用した親のカスケード削除
リレーショナル データベース システムでは、子の行を削除すると、多くの場合、親の削除が必要になります。他の子によって参照されなくなりました。このタスクは、PostgreSQL バージョン 9.1 以降で、データ変更 CTE (共通テーブル式) を使用して実行できます。
データ変更 CTE アプローチ
<code class="sql">WITH del_child AS ( DELETE FROM child WHERE child_id = 1 RETURNING parent_id, child_id ) DELETE FROM parent p USING del_child x WHERE p.parent_id = x.parent_id AND NOT EXISTS ( SELECT FROM child c WHERE c.parent_id = x.parent_id AND c.child_id <> x.child_id -- ! );</code>
これCTE はまず、指定された子行を削除します。次に、親 ID と削除された子 ID を返します。 2 番目の DELETE ステートメントは、この情報を使用して、他に子が残っていない場合に親行を削除します。条件 c.child_id <> x.child_id は、削除される子以外の子のみが考慮されることを保証します。
競合状態の排除
同時トランザクションが予期しない結果を引き起こす可能性がある潜在的な競合状態を防ぐため、削除プロセスの前に親行をロックできます。これは、CTE で FOR NO KEY UPDATE 句を使用して親行をロックすることによって実現されます。
<code class="sql">WITH lock_parent AS ( SELECT p.parent_id, c.child_id FROM child c JOIN parent p ON p.parent_id = c.parent_id WHERE c.child_id = 12 -- provide child_id here once FOR NO KEY UPDATE -- locks parent row. ) , del_child AS ( DELETE FROM child c USING lock_parent l WHERE c.child_id = l.child_id ) DELETE FROM parent p USING lock_parent l WHERE p.parent_id = l.parent_id AND NOT EXISTS ( SELECT FROM child c WHERE c.parent_id = l.parent_id AND c.child_id <> l.child_id -- ! );</code>
このアプローチでは、危険な DELETE 操作の実行が 1 つのトランザクションに制限され、同時実行の可能性が効果的に排除されます。干渉。
以上がPostgreSQL で外部キー制約を使用したカスケード親削除を実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。