Mysql 错误 1452 - 无法添加或更新子行:外键约束失败
我遇到了一个奇怪的问题。 我正在尝试向引用另一个表的一个表添加外键,但由于某种原因失败了。 由于我对 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
I'm having a bit of a strange problem. I'm trying to add a foreign key to one table that references another, but it is failing for some reason. With my limited knowledge of MySQL, the only thing that could possibly be suspect is that there is a foreign key on a different table referencing the one I am trying to reference.
I've done a SHOW CREATE TABLE
query on both tables, sourcecodes_tags
is the table with the foreign key, sourcecodes
is the referenced table.
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
This is the code that generates the error:
ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(21)
您的
sourcecodes_tags
表中很可能包含sourcecode_id
值,而这些值已不再存在于您的sourcecodes
表中。 你必须先摆脱那些。下面是一个可以找到这些 ID 的查询:
Quite likely your
sourcecodes_tags
table containssourcecode_id
values that no longer exists in yoursourcecodes
table. You have to get rid of those first.Here's a query that can find those IDs:
我的 MySQL 数据库也遇到了同样的问题,但最终我得到了一个适合我的解决方案。
因为在我的表中,从 mysql 的角度来看一切都很好(两个表都应该使用 InnoDB 引擎,并且每列的数据类型应该是参与外键约束的相同类型)。
我所做的唯一一件事就是禁用外键检查,然后在执行外键操作后启用它。
我采取的步骤:
I had the same issue with my MySQL database but finally, I got a solution which worked for me.
Since in my table everything was fine from the mysql point of view(both tables should use InnoDB engine and the datatype of each column should be of the same type which takes part in foreign key constraint).
The only thing that I did was to disable the foreign key check and later on enabled it after performing the foreign key operation.
Steps that I took:
使用
NOT IN
查找约束的位置约束:因此,更具体地说:
编辑:
IN
和众所周知,NOT IN
运算符比JOIN
运算符快得多,并且更容易构造和重复。Use
NOT IN
to find where constraints are constraining:so, more specifically:
EDIT:
IN
andNOT IN
operators are known to be much faster than theJOIN
operators, as well as much easier to construct, and repeat.截断表,然后尝试添加 FK 约束。
我知道这个解决方案有点尴尬,但它确实 100% 有效。 但我同意这不是处理问题的理想解决方案,但我希望它有所帮助。
Truncate the tables and then try adding the FK Constraint.
I know this solution is a bit awkward but it does work 100%. But I agree that this is not an ideal solution to deal with problem, but I hope it helps.
对我来说,这个问题有点不同,而且非常容易检查和解决。
您必须确保两个表都是 InnoDB。 如果其中一张表(即引用表)是MyISAM,则约束将失败。
For me, this problem was a little different and super easy to check and solve.
You must ensure BOTH of your tables are InnoDB. If one of the tables, namely the reference table is a MyISAM, the constraint will fail.
当将parent.id 的外键设置为child.column 时,如果child.column 的值为0 并且没有parent.id 值为0,也会发生这种情况
您需要确保每个child.column 为NULL 或具有值 。
现在我读到了 nos 写的声明,这就是他正在验证的内容
This also happens when setting a foreign key to parent.id to child.column if the child.column has a value of 0 already and no parent.id value is 0
You would need to ensure that each child.column is NULL or has value that exists in parent.id
And now that I read the statement nos wrote, that's what he is validating.
我今天也遇到了同样的问题。 我测试了四件事,其中一些已经在此处提到:
子列中是否有父列中不存在的值(除了 NULL,如果子列可为空)
子列和父列是否具有相同的数据类型?
子
您引用的父列上是否有索引? 出于性能原因,MySQL 似乎需要这样做(http ://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html)
这个为我解决了这个问题:两个表是否具有相同的排序规则?
我有一个 UTF-8 格式的表,另一个是 iso-something 格式的表。 那行不通。 将 iso 表更改为 UTF-8 排序规则后,可以毫无问题地添加约束。 就我而言,phpMyAdmin 甚至没有在用于创建外键约束的下拉列表中显示 iso 编码的子表。
I had the same problem today. I tested for four things, some of them already mentioned here:
Are there any values in your child column that don't exist in the parent column (besides NULL, if the child column is nullable)
Do child and parent columns have the same datatype?
Is there an index on the parent column you are referencing? MySQL seems to require this for performance reasons (http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html)
And this one solved it for me: Do both tables have identical collation?
I had one table in UTF-8 and the other in iso-something. That didn't work. After changing the iso-table to UTF-8 collation the constraints could be added without problems. In my case, phpMyAdmin didn't even show the child table in iso-encoding in the dropdown for creating the foreign key constraint.
似乎第 0 行列有一些无效值,它不是有效的外键,因此 MySQL 无法为其设置外键约束。
您可以按照以下步骤操作:
删除您尝试为其设置 FK 约束的列。
再次添加,并将其默认值设置为NULL。
尝试再次为其设置外键约束。
It seems there is some invalid value for the column line 0 that is not a valid foreign key so MySQL cannot set a foreign key constraint for it.
You can follow these steps:
Drop the column which you have tried to set FK constraint for.
Add it again and set its default value as NULL.
Try to set a foreign key constraint for it again.
我遇到了同样的问题,我检查了表的行,发现与我想要定义外键的字段的值存在一些不兼容。 我更正了这些值,再次尝试,问题就解决了。
I'd the same problem, I checked rows of my tables and found there was some incompatibility with the value of fields that I wanted to define a foreign key. I corrected those value, tried again and the problem was solved.
我最终删除了表中的所有数据,然后再次运行 alter。 有用。 虽然不是很出色,但它节省了很多时间,特别是您的应用程序仍处于开发阶段,没有任何客户数据。
I end up delete all the data in my table, and run alter again. It works. Not the brilliant one, but it save a lot time, especially your application is still in development stage without any customer data.
尝试这个
try this
清空两个表的数据并运行命令。 它会起作用的。
Empty both your tables' data and run the command. It will work.
我在三个不同的时间遇到了完全相同的问题。 在每种情况下,都是因为我的一个(或多个)记录不符合新的外键。 在尝试添加键本身之前,您可能需要更新现有记录以遵循外键的语法约束。 下面的示例通常应该隔离问题记录:
repeat
AND (candidate key) <> (下一个建议的外键值)
在外键中每个值的查询中。如果您有大量记录,这可能会很困难,但如果您的表相当小,则不会花费太长时间。 我对 SQL 语法并不是很了解,但这总是为我解决了这个问题。
I had this exact same problem about three different times. In each instance it was because one (or more) of my records did not conform to the new foreign key. You may want to update your existing records to follow the syntax constraints of the foreign key before trying to add the key itself. The following example should generally isolate the problem records:
repeat
AND (candidate key) <> (next proposed foreign key value)
within your query for each value in the foreign key.If you have a ton of records this can be difficult, but if your table is reasonably small it shouldn't take too long. I'm not super amazing in SQL syntax, but this has always isolated the issue for me.
我在使用 Laravel 和 eloquent 时遇到此错误,尝试创建外键链接会导致 1452。问题是链接表中缺少数据。
请参阅此处的示例: http://mstd.eu/index.php/2016/12/02/laravel-eloquent-integrity-constraint-violation-1452-foreign-key-constraint/
I was getting this error when using Laravel and eloquent, trying to make a foreign key link would cause a 1452. The problem was lack of data in the linked table.
Please see here for an example: http://mstd.eu/index.php/2016/12/02/laravel-eloquent-integrity-constraint-violation-1452-foreign-key-constraint/
您只需要回答一个问题:
您的表是否已存储数据? (特别是包含外键的表。)
如果答案是肯定的,那么您唯一需要做的就是删除所有记录,然后您可以随意向表中添加任何外键。
录入数据后无法添加外键的原因是表不一致,在之前填满数据的表上添加新的外键如何处理?
如果答案是否定的,请按照其他说明进行操作。
You just need to answer one question:
Is your table already storing data? (Especially the table included foreign key.)
If the answer is yes, then the only thing you need to do is to delete all the records, then you are free to add any foreign key to your table.
The reason you cannot add in foreign key after data entries is due to the table inconsistency, how are you going to deal with a new foreign key on the former data-filled the table?
If the answer is no, then follow other instructions.
我正在准备这个解决方案,这个例子可能会有所帮助。
我的数据库有两个表(电子邮件和信用卡),其 ID 具有主键。 另一个表(客户端)将此表 ID 称为外键。 我有理由将电子邮件与客户数据分开。
首先,我插入引用表(电子邮件、信用卡)的行数据,然后获取每个表的 ID,第三个表(客户端)需要这些 ID。
如果您不首先在引用的表中插入行,那么当您在引用外键的第三个表中插入新行时,MySQL 将无法进行对应。
如果首先插入引用表的引用行,然后插入引用外键的行,则不会发生错误。
希望这可以帮助。
I was readying this solutions and this example may help.
My database have two tables (email and credit_card) with primary keys for their IDs. Another table (client) refers to this tables IDs as foreign keys. I have a reason to have the email apart from the client data.
First I insert the row data for the referenced tables (email, credit_card) then you get the ID for each, those IDs are needed in the third table (client).
If you don't insert first the rows in the referenced tables, MySQL wont be able to make the correspondences when you insert a new row in the third table that reference the foreign keys.
If you first insert the referenced rows for the referenced tables, then the row that refers to foreign keys, no error occurs.
Hope this helps.
确保该值位于另一个表中,否则您将在分配的相应列中收到此错误。
因此,如果将列分配给另一个表的行ID,请确保该表中有一行,否则会出现此错误。
Make sure the value is in the other table otherwise you will get this error, in the assigned corresponding column.
So if it is assigned column is assigned to a row id of another table , make sure there is a row that is in the table otherwise this error will appear.
你可以尝试这个例子
注意:如果你使用 phpmyadmin 只需取消选中启用外键检查
as 示例
希望这个解决方案可以解决您的问题:)
you can try this exapmple
Note : if you are using phpmyadmin just uncheck Enable foreign key checks
as example
hope this soloution fix your problem :)
应该有助于摆脱这些 ID。 或者,如果
sourcecode_id
中不允许null
,则删除这些行或将这些缺失值添加到sourcecodes
表中。should help to get rid of those IDs. Or if
null
is not allowed insourcecode_id
, then remove those rows or add those missing values to thesourcecodes
table.我遇到了同样的问题并找到了解决方案,在外键列上放置
NULL
而不是NOT NULL
。 这是一个查询:MySQL 已执行此查询!
I had the same problem and found solution, placing
NULL
instead ofNOT NULL
on foreign key column. Here is a query:MySQL has executed this query!
就我而言,我创建了一个具有相同结构的新表,创建了与其他表的关系,然后从有问题的旧表中提取了 CSV 中的数据,然后将 CSV 导入到新表并禁用了外键检查并且禁用了导入中断,我的所有数据都成功插入到没有问题的新表中,然后删除了旧表。
这对我有用。
In my case, I created a new table with the same structure, created the relationships with the other tables, then extracted the data in CSV from the old table that has the problem, then imported the CSV to the new table and disabled foreign key checking and disabled import interruption, all my data are inserted to the new table that has no problem successfully, then deleted the old table.
It worked for me.