当parentID和childID在同一张表上时如何删除级联?

问题描述 投票:2回答:3

我是一个名为成员的mysql表,基本上有两列:parentIDchildID。这样,我可以基于这两列创建一个层次树,例如:

parentID, ChildID
1,2
2,3
3,4

将在我的应用程序中生成一个树,其中以parentID = 1为根,2为第一节点,3为第二节点,4为第三节点,依此类推。

如果在这种情况下要从给定的parentID中删除所有节点,我该如何完成?

mysql cascade
3个回答
2
投票

您只需要确保已从子行到其父行设置了外键,并在外键上设置了ON DELETE CASCASDE选项。自引用表和单独表中的引用一样,效果很好。为了删除树,只需删除父节点。所有子行将被立即删除。

例如鉴于:

CREATE TABLE MyTable
(
  ID INT NOT NULL PRIMARY KEY,
  ParentID INT  NULL,
  CONSTRAINT FK_MT_Parent FOREIGN KEY (ParentID) REFERENCES MyTable(ID) ON DELETE CASCADE
);

-- And inserting two trees of data:
-- 1-2-3
--   └-4
-- 10 - 11
INSERT INTO MyTable(ID,ParentID) VALUES
    (1,null), (2,1), (3,2), (4,2),
    (10,null), (11,10);

我们可以通过简单地删除根节点来删除整个第一棵树:

DELETE FROM MYTable WHERE ID = 1;

SqlFiddle of same

但是请注意,从DocsCASCADE的深度有限制,删除:

级联操作嵌套的深度不得超过15级


0
投票

您是否尝试过使用MySQL JOIN示例来完成您的操作。

请检查sql fiddle

我已经通过使用内部联接的查询来设置此示例。如果传递WHERE mem1.parentID = '2',它将把所有具有2的记录删除到ChildID或parentID字段中。

DELETE mem2.* FROM
  member mem1
  INNER JOIN member mem2 ON mem2.ChildID = mem1.parentID OR mem1.parentID = mem2.parentID
  WHERE mem1.parentID = '2';

DELETE以上查询将删除parentID = '2'中具有childID和相同值的列。因此,输出是从member表中删除了两列。

[请检查并让我知道是否还有其他疑问/顾虑。


0
投票

基本上有两种方法:

  1. 递归循环并找到所有需要删除的记录
    SELECT ChildID FROM MyTable WHERE parentID = ?
    
    您可以通过此SQL获取ChildID的列表,然后再次运行该SQL,并将ChildID的列表作为“ parentID”,直到得到一个空列表。之后,将其全部删除
    DELETE FROM MyTable WHERE ChildID = ?
    
  2. 使用nested set model。您可以在互联网上找到许多教程,例如:managing hierachical data in my sql。然后,您可以删除所需的内容:
    DELETE w FROM MyTable w 
    INNER JOIN MyTable parent
    ON w.parentID = parent.ChildID
    WHERE w.lft BETWEEN parent.lft AND parent.rgt
        AND parent.parentID = ?
    
© www.soinside.com 2019 - 2024. All rights reserved.