我有一个奇怪的问题。我正在尝试将外键添加到一个引用另一个表的表中,但由于某种原因它失败了。由于我对 MySQL 的了解有限,唯一可能怀疑的是在另一个表上存在一个外键,该表引用了我试图引用的表。
我对两个表都进行了 SHOW CREATE TABLE
查询,sourcecodes_tags
是具有外键的表,sourcecodes
是引用的表。
CREATE TABLE `sourcecodes` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) unsigned NOT NULL,
`language_id` int(11) unsigned NOT NULL,
`category_id` int(11) unsigned NOT NULL,
`title` varchar(40) CHARACTER SET utf8 NOT NULL,
`description` text CHARACTER SET utf8 NOT NULL,
`views` int(11) unsigned NOT NULL,
`downloads` int(11) unsigned NOT NULL,
`time_posted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `language_id` (`language_id`),
KEY `category_id` (`category_id`),
CONSTRAINT `sourcecodes_ibfk_3` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sourcecodes_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sourcecodes_ibfk_2` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
CREATE TABLE `sourcecodes_tags` (
`sourcecode_id` int(11) unsigned NOT NULL,
`tag_id` int(11) unsigned NOT NULL,
KEY `sourcecode_id` (`sourcecode_id`),
KEY `tag_id` (`tag_id`),
CONSTRAINT `sourcecodes_tags_ibfk_1` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
这是生成错误的代码:
ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE
您的 sourcecodes_tags
表中很可能包含 sourcecodes
表中不再存在的 sourcecode_id
值。你必须先摆脱那些。
这是一个可以找到这些 ID 的查询:
SELECT DISTINCT sourcecode_id FROM
sourcecodes_tags tags LEFT JOIN sourcecodes sc ON tags.sourcecode_id=sc.id
WHERE sc.id IS NULL;
我的 MySQL 数据库也遇到了同样的问题,但最后,我得到了一个对我有用的解决方案。因为从 mysql 的角度来看,在我的表中一切都很好(两个表都应该使用 InnoDB 引擎,并且每列的数据类型应该是参与外键约束的相同类型)。我唯一做的就是禁用外键检查,然后在执行外键操作后启用它。我采取的步骤:
SET foreign_key_checks = 0;
alter table tblUsedDestination add constraint f_operatorId foreign key(iOperatorId) references tblOperators (iOperatorId); Query
OK, 8 rows affected (0.23 sec) Records: 8 Duplicates: 0 Warnings: 0
SET foreign_key_checks = 1;
使用 NOT IN
查找约束约束的位置:
SELECT column FROM table WHERE column NOT IN
(SELECT intended_foreign_key FROM another_table)
所以,更具体地说:
SELECT sourcecode_id FROM sourcecodes_tags WHERE sourcecode_id NOT IN
(SELECT id FROM sourcecodes)
编辑:已知 IN
和 NOT IN
运算符比 JOIN
运算符快得多,并且更容易构造和重复。
截断表,然后尝试添加 FK 约束。
我知道这个解决方案有点尴尬,但它确实 100% 有效。但我同意这不是处理问题的理想解决方案,但我希望它有所帮助。
对我来说,这个问题有点不同,而且超级容易检查和解决。
您必须确保您的两个表都是 InnoDB。如果其中一个表,即引用表是 MyISAM,则约束将失败。
SHOW TABLE STATUS WHERE Name = 't1';
ALTER TABLE t1 ENGINE=InnoDB;
如果 child.column 的值已经为 0 并且没有 parent.id 值为 0,则在将 parent.id 的外键设置为 child.column 时也会发生这种情况
您需要确保每个 child.column 为 NULL 或具有 parent.id 中存在的值
现在我阅读了 nos 所写的声明,这就是他正在验证的内容。
我今天遇到了同样的问题。我测试了四件事,其中一些已经在这里提到:
子列中是否存在父列中不存在的值(如果子列可以为空,则为 NULL) 子列和父列是否具有相同的数据类型?您引用的父列上是否有索引? MySQL 似乎出于性能原因需要这个 (http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html) 而这个为我解决了这个问题:两张表是否相同整理?
我有一张 UTF-8 表,另一张表是 iso-something。那没有用。将 iso-table 更改为 UTF-8 排序规则后,可以毫无问题地添加约束。就我而言,phpMyAdmin 甚至没有在下拉菜单中以 iso-encoding 显示子表以创建外键约束。
似乎第 0 列的某些无效值不是有效的外键,因此 MySQL 无法为其设置外键约束。
您可以按照以下步骤操作:
删除您尝试为其设置 FK 约束的列。再次添加它并将其默认值设置为 NULL。尝试再次为其设置外键约束。
我遇到了同样的问题,我检查了表的行,发现与我想定义外键的字段的值有些不兼容。我更正了这些值,再试一次,问题就解决了。
我最终删除了表中的所有数据,然后再次运行 alter。有用。不是很出色,但它节省了很多时间,尤其是您的应用程序仍处于开发阶段,没有任何客户数据。
尝试这个
SET foreign_key_checks = 0;
ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE
SET foreign_key_checks = 1;
我在三个不同的时间遇到了完全相同的问题。在每种情况下,都是因为我的一个(或多个)记录不符合新的外键。在尝试添加键本身之前,您可能希望更新现有记录以遵循外键的语法约束。下面的例子一般应该隔离问题记录:
SELECT * FROM (tablename)
WHERE (candidate key) <> (proposed foreign key value)
AND (candidate key) <> (next proposed foreign key value)
在查询中为外键中的每个值重复 AND (candidate key) <> (next proposed foreign key value)
。
如果您有大量记录,这可能会很困难,但如果您的表相当小,则不会花费太长时间。我在 SQL 语法方面并不是特别出色,但这对我来说总是孤立的问题。
清空两个表的数据并运行命令。它会起作用的。
我在使用 Laravel 和 eloquent 时遇到此错误,尝试建立外键链接会导致 1452。问题是链接表中缺少数据。
你只需要回答一个问题:
您的表是否已经存储数据? (特别是包含外键的表。)
如果答案是肯定的,那么您唯一需要做的就是删除所有记录,然后您可以自由地将任何外键添加到您的表中。
删除指令:从子表(包括外键表)到父表。
数据输入后无法添加外键的原因是由于表不一致,您将如何处理以前填充数据的表上的新外键?
如果答案是否定的,则按照其他说明进行操作。
我正在准备这个解决方案,这个例子可能会有所帮助。
我的数据库有两个表(email 和 credit_card),它们的 ID 具有主键。另一个表(客户端)将此表 ID 称为外键。我有理由将电子邮件与客户数据分开。
首先,我为引用的表(电子邮件、信用卡)插入行数据,然后您获得每个表的 ID,这些 ID 在第三个表(客户端)中是需要的。
如果您不首先在引用的表中插入行,那么当您在引用外键的第三个表中插入新行时,MySQL 将无法进行对应。
如果您首先为被引用的表插入被引用的行,然后是引用外键的行,则不会发生错误。
希望这可以帮助。
确保该值在另一个表中,否则您将在分配的相应列中收到此错误。
因此,如果将其分配的列分配给另一个表的行 id,请确保该表中有一行,否则会出现此错误。
你可以试试这个例子
START TRANSACTION;
SET foreign_key_checks = 0;
ALTER TABLE `job_definers` ADD CONSTRAINT `job_cities_foreign` FOREIGN KEY
(`job_cities`) REFERENCES `drop_down_lists`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
SET foreign_key_checks = 1;
COMMIT;
注意:如果您使用的是 phpmyadmin,只需取消选中启用外键检查
https://i.stack.imgur.com/xrQER.png
希望这个解决方案可以解决您的问题:)
UPDATE sourcecodes_tags
SET sourcecode_id = NULL
WHERE sourcecode_id NOT IN (
SELECT id FROM sourcecodes);
应该有助于摆脱这些ID。或者,如果 sourcecode_id
中不允许使用 null
,则删除这些行或将这些缺失值添加到 sourcecodes
表中。
我遇到了同样的问题并找到了解决方案,将 NULL
而不是 NOT NULL
放在外键列上。这是一个查询:
ALTER TABLE `db`.`table1`
ADD COLUMN `col_table2_fk` INT UNSIGNED NULL,
ADD INDEX `col_table2_fk_idx` (`col_table2_fk` ASC),
ADD CONSTRAINT `col_table2_fk1`
FOREIGN KEY (`col_table2_fk`)
REFERENCES `db`.`table2` (`table2_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
MySQL 已经执行了这个查询!
就我而言,我创建了一个具有相同结构的新表,创建了与其他表的关系,然后从有问题的旧表中提取 CSV 中的数据,然后将 CSV 导入新表并禁用外键检查并禁用导入中断,我的所有数据都成功插入到没有问题的新表中,然后删除了旧表。
它对我有用。
UPDATE sourcecodes_tags SET sourcecode_id = NULL WHERE sourcecode_id NOT IN (SELECT id FROM sourcecodes)
应该有助于摆脱这些 ID。或者,如果sourcecode_id
中不允许使用null
,则删除这些行或将这些缺失值添加到sourcecodes
表中。SELECT Tchild.id FROM Tchild INNER JOIN Tmain ON Tmain.id = Tchild.fk_id WHERE Tmain.id IS NULL
没有返回任何东西,所以问题出在其他地方!?UPDATE `homestead`.`automations` SET `deleted_at`=NULL WHERE deleted_at IS NOT NULL;
,它根本不涉及外键,所以我很困惑。但是我的联系人表缺少自动化表所引用的一些记录这一事实导致它抛出此“错误代码:1452。无法添加或更新子行:外键约束失败”。