【问题标题】:MySQL InnoDB - create CASCADE foreign key constraint when data already exists that violates it?MySQL InnoDB - 当已经存在违反它的数据时创建 CASCADE 外键约束?
【发布时间】:2011-05-12 02:26:41
【问题描述】:

我有一个最初位于 MyISAM 中的数据库,因此没有外键约束。结果,有相当多的孤立行,其中外键引用的记录已被删除。

为了解决这个问题,我决定转换为 InnoDB 并添加外键,并使用 CASCADE 进行更新和删除。但是,当我尝试添加外键时,我收到这样的错误(来自 Navicat 8 控制台):

1452 - Cannot add or update a child row: a foreign key constraint fails 
(`database`.`#sql-1358_38d`, CONSTRAINT `#sql-1358_38d_ibfk_1` FOREIGN KEY 
(`manufacturerID`) REFERENCES `manufacturer` (`ID`) ON DE)

我知道它为什么这样做 - 因为孤立的行。有没有办法让约束的创建自动清除这些行?遍历所有表并找到孤立行将需要很长时间。

这是我正在运行的查询之一,以防万一:

ALTER TABLE part_number ADD CONSTRAINT
FOREIGN KEY(manufacturerID)
REFERENCES manufacturer(ID)
ON DELETE CASCADE
ON UPDATE CASCADE;

【问题讨论】:

    标签: mysql foreign-keys innodb


    【解决方案1】:

    编写一个查找孤立行的查询,然后使用它来删除。例如

    SELECT part_number.id FROM part_number LEFT JOIN manufacturer ON (manufacturer.ID = part_number.manufacturerID) where manufacturer.ID IS NULL

    【讨论】:

    • 嗯,这基本上就是我已经开始做的事情,但这需要一段时间,只是想知道是否有能力不必手动完成。
    【解决方案2】:

    您需要先删除所有不相关的记录,然后才能添加约束。

    你可以通过两种方式做到这一点。

    1 使用不存在()

    DELETE FROM part_number
     WHERE NOT EXISTS (
               select id from manufacturer
                where part_number.manufacturerID = manufacturer.ID
           )
    

    2。使用临时表(有点难看,但我也会发布)

    -- create a temporary table
    CREATE TEMPORARY TABLE `temp_ids`
    (
      `id` INTEGER
    );
    
    -- store all id's that need to be deleted
    INSERT INTO `temp_ids`
    SELECT part_number.id FROM part_number LEFT JOIN manufacturer ON (manufacturer.ID = part_number.manufacturerID)
    WHERE ISNULL(`manufacturer.ID);
    
    -- delete them
    DELETE
    FROM part_number
    WHERE id IN (
      SELECT `id` FROM `temp_ids`
    );
    
    -- drop the table
    DROP TEMPORARY TABLE `temp_ids`;
    

    查看我的相关问题:Handling database integrity

    删除所有“死”记录后,您将能够添加约束。

    希望这对你有用:)

    【讨论】:

      猜你喜欢
      • 2014-10-24
      • 1970-01-01
      • 2016-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-19
      • 2010-12-07
      相关资源
      最近更新 更多