Zim*_*Zim 234 mysql foreign-keys mysql-error-1452
我有一个奇怪的问题.我正在尝试将一个外键添加到一个引用另一个表的表中,但由于某种原因它失败了.由于我对MySQL的了解有限,唯一可能怀疑的是在不同的表上有一个外键引用我想要引用的那个.
这是我的表关系的图片,通过phpMyAdmin:Relationships生成
我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
Run Code Online (Sandbox Code Playgroud)
如果有人能告诉我这里发生了什么,我没有正式的训练或任何与MySQL :)
谢谢.
编辑:这是生成错误的代码:
ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE
Run Code Online (Sandbox Code Playgroud)
nos*_*nos 224
您的sourcecodes_tags表很可能包含表中sourcecode_id不再存在的值sourcecodes.你必须先摆脱那些.
这是一个可以找到这些ID的查询:
SELECT DISTINCT sourcecode_id FROM
sourcecodes_tags tags LEFT JOIN sourcecodes sc ON tags.sourcecode_id=sc.id
WHERE sc.id IS NULL;
Run Code Online (Sandbox Code Playgroud)
小智 96
我的mysql数据库遇到了同样的问题,但最后我得到了一个适合我的解决方案.
因为在我的表中从mysql的角度来看一切都很好(两个表都应该使用Innodb引擎,每个列的数据类型应该是参与外键约束的相同类型).
我所做的只是禁用外键检查,然后在执行外键操作后启用它.
我采取的步骤:
Run Code Online (Sandbox Code Playgroud)SET foreign_key_checks = 0;
Rya*_*ard 55
使用NOT IN以找到约束制约:
SELECT column FROM table WHERE column NOT IN
(SELECT intended_foreign_key FROM another_table)
Run Code Online (Sandbox Code Playgroud)
所以,更具体地说:
SELECT sourcecode_id FROM sourcecodes_tags WHERE sourcecode_id NOT IN
(SELECT id FROM sourcecodes)
Run Code Online (Sandbox Code Playgroud)
编辑:IN和NOT IN运营商被称为是比快很多JOIN运营商,以及更容易构建,并重复.
Sha*_*ran 23
我知道这个解决方案有点尴尬,但它确实可以100%工作.但我同意这不是处理问题的理想解决方案,但我希望它有所帮助.
zmo*_*eca 16
对我来说,这个问题有点不同,超级易于检查和解决.
您必须确保表的两个是InnoDB.如果其中一个表(即参考表是MyISAM),则约束将失败.
SHOW TABLE STATUS WHERE Name = 't1';
ALTER TABLE t1 ENGINE=InnoDB;
Run Code Online (Sandbox Code Playgroud)
fyr*_*rye 14
如果child.column的值已经为0且parent.id值为0,那么在将parent.id的外键设置为child.column时也会发生这种情况.
您需要确保每个child.column为NULL或具有parent.id中存在的值
现在,我读到了nos写的声明,这就是他正在验证的内容.
Mic*_*wig 14
我今天遇到了同样的问题.我测试了四件事,其中一些已经在这里提到:
您的子列中是否存在父列中不存在的值(除了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编码显示子表.
似乎有一些无效值的列,如0,这不是一个有效的外键,所以MySQL不能为它设置外键约束.
您可以按照以下步骤操作:
删除您尝试为其设置FK约束的列.
再次添加它并将其默认值设置为NULL.
尝试再次为它设置外键约束.