PostgreSQL中如何實作帶有外鍵約束的級聯父級刪除?

Linda Hamilton
發布: 2024-10-31 22:34:29
原創
971 人瀏覽過

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。如果父行沒有其他剩餘子行,第二個 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 操作的執行限制在單一事務中,有效消除了並發的可能性幹擾。

以上是PostgreSQL中如何實作帶有外鍵約束的級聯父級刪除?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板