< h2>子どもが参照していない場合に親の削除を保証する;他の子によって参照されなくなった場合でも構いません。これは、データ変更 CTE を使用して PostgreSQL で実現でき、競合状態のリスクを最小限に抑えます。
次の PostgreSQL ステートメントを考えてみましょう:
<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>
ログイン後にコピー
その仕組みは次のとおりです:
del_child CTE は、child_id = 1 の子行を削除します。- DELETE ステートメントは、del_child から返されたparent_id に基づいて親行を削除しようとします。ただし、親を削除するのは、その親を参照している他の子がない場合のみです。これは、異なる child_id (存在しないサブクエリ) を持つ他の子の存在をチェックすることによって実現されます。
- 条件 c.child_id <> x.child_id により、削除されたばかりの子行がサブクエリによって確実に除外されます。
-
競合状態の排除
競合状態の可能性を完全に排除するには、子と親の両方を削除する前に、親行をロックすることをお勧めします。これにより、一度に 1 つのトランザクションのみがこの操作を処理できるようになり、複数のトランザクションによって子が削除され、親が孤立したままになることがなくなります。
行ロックを使用した更新されたステートメントは次のとおりです。
以上がPostgreSQL で子が参照していないときに親を確実に削除する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。