如何添加外键(MySQL)

Ker*_*rry 31 mysql foreign-keys

我是SQL的新手,我正在尝试执行一个简单的ALTER TABLE来创建一个新列并将其用作外键来引用我数据库中的另一个简单表.我把两个表都改成了InnoDB

但是,在执行ALTER TABLE代码时,我收到以下错误:

Error   1452    Cannot add or update a child row: 
a foreign key constraint fails (`toys`.<result 2 when 
explaining filename '#sql-6d4_6'>, CONSTRAINT 
`#sql-6d4_6_ibfk_1` FOREIGN KEY (`toy_id`) REFERENCES `toys` (`toy_id`))    
Run Code Online (Sandbox Code Playgroud)

以下是两个表的DESC:

表格1:

FIELD       TYPE     NULL   KEY     EXTRA
toy_id      int(11)  NO     PRI     auto_increment
toy varchar(50) YES         
Run Code Online (Sandbox Code Playgroud)

表2:

FIELD       TYPE        NULL   KEY     EXTRA
boy_id      int(11)     NO     PRI      auto_increment
boy         varchar(50) YES 
Run Code Online (Sandbox Code Playgroud)

这是我试图执行的ALTER查询:

    ALTER TABLE boys
    ADD COLUMN toy_id INT NOT NULL,
    ADD CONSTRAINT toys_toy_id_fk
    FOREIGN KEY(toy_id)
    REFERENCES toys(toy_id);
Run Code Online (Sandbox Code Playgroud)

我一直在试图弄明白,但没有运气.在此先感谢,请善待这个新手:)

编辑:

以下是两个表的SHOW CREATE TABLE:

表格1:

    CREATE TABLE `toys` (
      `toy_id` int(11) NOT NULL AUTO_INCREMENT,
      `toy` varchar(50) DEFAULT NULL,
      PRIMARY KEY (`toy_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)

表2:

    CREATE TABLE `boys` (
      `boy_id` int(11) NOT NULL AUTO_INCREMENT,
      `boy` varchar(50) DEFAULT NULL,
      PRIMARY KEY (`boy_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)

Bil*_*win 45

当列被限制为与父表中的值匹配的值时,您不能将NOT NULL列添加到具有多于零行的表,并且仅具有NULL值,因为它是没有DEFAULT的新的未填充列.

解决方法是分阶段执行:添加列,但不要将其声明为NOT NULL,并且不要声明外键.

ALTER TABLE boys
 ADD COLUMN toy_id INT;
Run Code Online (Sandbox Code Playgroud)

然后使用与玩具表中的某些值匹配的有效数据填充它.

UPDATE boys SET toy_id = ...;
Run Code Online (Sandbox Code Playgroud)

然后将列更改为NOT NULL,并创建约束:

ALTER TABLE boys MODIFY COLUMN toy_id INT NOT NULL,
 ADD CONSTRAINT toys_toy_id_fk
 FOREIGN KEY(toy_id)
 REFERENCES toys(toy_id);
Run Code Online (Sandbox Code Playgroud)