首页  >  文章  >  数据库  >  当没有子级引用它时,如何确保 PostgreSQL 中的父级删除?

当没有子级引用它时,如何确保 PostgreSQL 中的父级删除?

Linda Hamilton
Linda Hamilton原创
2024-10-29 15:41:02831浏览

How to Ensure Parent Deletion in PostgreSQL When No Children Reference It?

确保父级在未被任何子级引用时被删除

删除子行时,通常需要删除父级,如下所示如果它不再被任何其他孩子引用就好了。这可以在 PostgreSQL 中使用数据修改 CTE 来实现,从而最大限度地降低竞争条件的风险。

考虑以下 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 的任何其他子项(NOT EXISTS 子查询)来实现的。
  • 条件 c.child_id

消除竞争条件

彻底消除竞争条件的可能性,建议在删除子行和父行之前锁定父行。这可确保一次只有一个事务可以处理此操作,从而防止多个事务删除子事务并使父事务孤立。

这是带有行锁定的更新语句:

<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>

以上是当没有子级引用它时,如何确保 PostgreSQL 中的父级删除?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn