帶外鍵約束的級聯父級刪除
在關聯式資料庫系統中,刪除子行通常需要刪除父行(如果是)不再被任何其他孩子引用。此任務可以在 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中文網其他相關文章!