代码之家  ›  专栏  ›  技术社区  ›  jmccartie

删除层次结构中的孤立项

  •  1
  • jmccartie  · 技术社区  · 16 年前

    我在MySQL中有一个项目列表,通过“parent_id”列连接。

    假设列为:id、name、parent\u id

    1) 是否存在一个有效且高效的MySQL调用,该调用将返回其父项不再存在的所有项的ID?

    2) 在PHP中,我想我可以将MySQL中的这些孤立ID放入一个数组中,然后运行foreach循环并删除每个ID?

    5 回复  |  直到 16 年前
        1
  •  4
  •   Paolo Bergantino    16 年前

    Foreign Key Constraints ON DELETE CASCADE 设置外键关系时的选项。

    文档中的一个示例:

    CREATE TABLE parent (id INT NOT NULL,
                         PRIMARY KEY (id)) ENGINE=INNODB;
    
    CREATE TABLE child (id INT, parent_id INT,
                        INDEX par_ind (parent_id),
                        FOREIGN KEY (parent_id) REFERENCES parent(id)
                        ON DELETE CASCADE) ENGINE=INNODB;
    

    这样,如果要添加父行和匹配的子行,如下所示:

    INSERT INTO parent (id) VALUES (1);
    INSERT INTO child (id, parent_id) VALUES (1,1);
    

    然后像这样删除父对象:

    DELETE FROM parent WHERE id = 1;
    

    您将发现匹配的子记录已消失。在我看来,这是最好的办法。

    :要在1个表中执行此操作,请执行以下操作:

    CREATE TABLE parent (
        id INT NOT NULL,
        name varchar(250) not null,
        parent_id INT NULL,
        FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE,
        PRIMARY KEY (id)
    ) ENGINE=INNODB
    

    然后,如果添加两行,一行引用另一行:

    INSERT INTO parent (id,name,parent_id)
    VALUES ('1', 'Test 1', NULL), ('2', 'Test 2', '1')
    

    id=1的父项中删除;
    

    parent_id 第1页。

        2
  •  2
  •   andri andri    16 年前

    我猜最初的作者想的是分层查询中的一些东西。

    CONNECT BY 实现你想要的)。

    删除所有孤立项的最简单方法可能是执行如下查询:

      SELECT t1.id 
        FROM table t1
          LEFT JOIN table t2 ON t2.id = t1.parent_id
        WHERE t2.id IS NULL
    

    这将从中生成所有行 table

    将其与一个PHP脚本配对,该脚本将持续执行查询并删除任何结果,经过几次迭代后,您的表应该没有孤立项(整个过程可能会合并到一个DELETE语句中,您可以在while循环中执行)。

    另外,确保显式跳过层次结构的头部,否则最终会得到一个空表(根据定义,头部是孤立的)。

        3
  •  2
  •   zombat    16 年前

    http://www.sitepoint.com/article/hierarchical-data-database/1/

    从这样的结构中检索数据不仅非常高效(单次选择并获得所有子级),而且还可以在单次delete语句中删除树的整个分支。

        4
  •  1
  •   Ólafur Waage    16 年前

    右连接通常用于查找其他数据库中的孤立项。但这也可以通过左连接实现。

    Here is

        5
  •  1
  •   St. John Johnson    16 年前

    另一种选择(如果您没有使用InnoDB,+1 Paolo)是使用 Delete Triggers 在父MySQL表上。

    请记住,使用delete触发器时,删除行由

    DELIMITER //
    
    CREATE TRIGGER delete_clean BEFORE DELETE ON Parent
    FOR EACH ROW
    BEGIN
      DELETE * FROM Parent WHERE Parent.parent_id = OLD.id;
    END //
    
    DELIMITER ;