ホームページ  >  記事  >  データベース  >  PostgreSQL で外部キー制約を使用したカスケード親削除を実装するにはどうすればよいですか?

PostgreSQL で外部キー制約を使用したカスケード親削除を実装するにはどうすればよいですか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-10-31 22:34:29868ブラウズ

How to Implement Cascading Parent Deletion with Foreign Key Constraints in PostgreSQL?

外部キー制約を使用した親のカスケード削除

リレーショナル データベース システムでは、子の行を削除すると、多くの場合、親の削除が必要になります。他の子によって参照されなくなりました。このタスクは、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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。