【问题标题】:How to recursively delete items from table?如何从表中递归删除项目?
【发布时间】:2012-03-04 18:59:53
【问题描述】:

我有一个 MySQL 表“文件夹”:

CREATE TABLE IF NOT EXISTS `folders` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `folder_key` varchar(40) NOT NULL,
  `parent_key` varchar(40) NOT NULL,
  `name` varchar(16) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

我不使用整数 ID,只使用键(字母数字哈希,我已将其替换为单词以使事情更清晰)。所以,folder_key & parent_key 是 SHA-1 哈希(在我的实际应用中)。

INSERT INTO `folders` (`id`, `folder_key`, `parent_key`, `name`) VALUES
(1, 'sun', 'root', '1'),
(2, 'moon', 'sun', '1.1'),
(3, 'jupiter', 'moon', '1.1.1'),
(4, 'mars', 'root', '2');

如您所见,第一项也有一个 parent_key,它是一个根键。

测试用例: 如果我想删除带有folder_key === moon (1.1) 的项目,它还应该删除其子元素,在这种情况下,它是带有folder_key === jupiter (1.1) 的项目.1) 等等...

假设我想删除多个项目,所以我这样做:

DELETE from folders WHERE folder_key IN('moon', 'mars'); 执行后,该表应该只有一项folder_key === sun

所以,问题是: 如何使用 MySQL 触发器、ON DELETE CASCADE 或 ... 从具有一个或多个文件夹键(递归)的表中删除项目?

谢谢。

【问题讨论】:

    标签: mysql recursion cascading-deletes


    【解决方案1】:

    这个模型是不可能的

    1. 而不是 root 使用 NULL ,所以你可以使用 InnoDB Foreign Key + Cascade Delete。
    2. 不要使用字符串 parent_key,而是使用 id(例如 sun = 1, moon = 2)

    其他方法是更改​​数据模型,因此您可以轻松选择元素的任何后代 - 参见例如 http://www.sitepoint.com/hierarchical-data-database-2/

    【讨论】:

      【解决方案2】:

      您可以在 folders 上添加 FOREIGN KEY,并使用 CASCADE 选项进行删除:

      ALTER TABLE `folders` ADD CONSTRAINT `FK_folder_parent` FOREIGN KEY `FK_folder_parent` (`parent_key`)
      REFERENCES `folders` (`folder_key`)
      ON DELETE CASCADE
      ON UPDATE CASCADE
      

      http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html

      【讨论】:

      • 错误是什么?语法错误还是您的值不匹配?我看到你parent_key 不为空?您应该将根文件夹设为 NULL,对吧?
      • 非常感谢。我通过更改模型解决了我的问题。
      【解决方案3】:

      与其存储“父键”值,不如存储它们的 id

      CREATE TABLE IF NOT EXISTS `folders` (
        `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
        `folder_key` varchar(40) NOT NULL,
        `parent_key` int(11) NOT NULL,
        `name` varchar(16) NOT NULL,
        PRIMARY KEY (`id`)
      foreign key(`parent_key`) on delete cascade
      ) ENGINE=InnoDB;
      

      【讨论】:

        【解决方案4】:

        @Naveen

        在创建级联删除约束时应该使用相同的数据类型。现在你有一个无符号整数和一个有符号整数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-18
          • 2010-09-19
          • 2023-04-03
          • 1970-01-01
          • 2018-09-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多