将自引用数据插入复制表

时间:2014-07-21 12:06:49

标签: mysql sql foreign-keys foreign-key-relationship

我的桌面上有一个自引用外键约束。因为我正在转换架构,所以我想将现有数据复制到一个具有(或多或少)相同结构的新表中:

CREATE TABLE test(
  id INT NOT NULL PRIMARY KEY,
  parent INT,
  FOREIGN KEY (parent) REFERENCES test(id)
);

CREATE TABLE copy(
  id INT NOT NULL PRIMARY KEY,
  parent INT,
  FOREIGN KEY (parent) REFERENCES copy(id) 
);

然而,当inserting the data

INSERT INTO copy(id, parent) SELECT id, parent FROM test;

MySQL给了我常见的完整性错误:

Error Code: 1452. Cannot add or update a child row:
    a foreign key constraint fails (`test`.`copy`, CONSTRAINT `copy_ibfk_1`
    FOREIGN KEY (`parent`) REFERENCES `copy` (`id`))

似乎MySQL在插入每一行后检查约束,而不是在整个插入后检查它。完全相同的示例works fine in PostgreSQL

有没有其他方法可以插入这些数据,还是我坚持这样做两步呢?

INSERT INTO copy(id) SELECT id FROM test;
UPDATE copy
JOIN test ON test.id = copy.id
SET copy.parent = test.parent;

1 个答案:

答案 0 :(得分:1)

您可以使用

SET FOREIGN_KEY_CHECKS=0;
在INSERT和

之前

SET FOREIGN_KEY_CHECKS=1;

禁用外键约束检查后,您不必担心插入的顺序:

请参阅foreign_key_checks

的文档
  

FOREIGN_KEY_CHECKS

     

如果设置为1(默认值),InnoDB表的外键约束   检查。如果设置为0,则忽略此类约束。 [...]通常   在正常操作期间启用此设置,以强制执行   参照完整性。禁用外键检查可能很有用   以不同于所需的顺序重新加载这些表   他们的父母/子女关系。请参见第14.6.6节“InnoDB和   外键约束“。 [...]

     

注意

     

将foreign_key_checks设置为1不会触发扫描   现有的表格数据。因此,行添加到表中的同时   foreign_key_checks = 0将不会被验证是否一致。

CREATE TABLE test(
  id INT NOT NULL PRIMARY KEY,
  parent INT,
  FOREIGN KEY (parent) REFERENCES test(id) 
);

CREATE TABLE copy(
  id INT NOT NULL PRIMARY KEY,
  parent INT,
  FOREIGN KEY (parent) REFERENCES copy(id) 
);

INSERT INTO test(id, parent) VALUES(1, null);
INSERT INTO test(id, parent) VALUES(2, 1);
INSERT INTO test(id, parent) VALUES(3, null);
INSERT INTO test(id, parent) VALUES(4, 2);
UPDATE test SET parent=3 WHERE id=1;

SET FOREIGN_KEY_CHECKS=0;

-- Success with MySQL
INSERT INTO copy(id, parent) SELECT id, parent FROM test;

SET FOREIGN_KEY_CHECKS=1;

您的更新小提琴:http://sqlfiddle.com/#!2/ae623/1