6

刚刚在Mac OS X 10.6上安装了MySQL 5.5,并且在很多表上有一个奇怪的问题。下面是一个例子。如果不应该插入一行,则会出现外键约束失败。它引用的外键确实存在。有任何想法吗?当外键存在时,MySQL 5.5外键约束失败

mysql> show create table Language; 
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Table | Create Table                                                                                                                            | 
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Language | CREATE TABLE `Language` (
    `Id` int(11) NOT NULL AUTO_INCREMENT, 
    `Code` varchar(2) NOT NULL, 
    `Name` varchar(63) CHARACTER SET utf8 DEFAULT NULL, 
    `Variant` varchar(63) CHARACTER SET utf8 DEFAULT NULL, 
    `Country_Id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`Id`), 
    UNIQUE KEY `Code` (`Code`,`Country_Id`,`Variant`), 
    KEY `FKA3ACF7789C1796EB` (`Country_Id`), 
    CONSTRAINT `FKA3ACF7789C1796EB` FOREIGN KEY (`Country_Id`) REFERENCES `Country` (`Id`) 
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 | 
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

mysql> show create table Language_Phrases; 
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Table   | Create Table                                                                                     | 
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Language_Phrases | CREATE TABLE `Language_Phrases` (
    `Language_Id` int(11) NOT NULL, 
    `Phrase` varchar(255) DEFAULT NULL, 
    `Label` varchar(255) NOT NULL, 
    PRIMARY KEY (`Language_Id`,`Label`), 
    KEY `FK8B4876F3AEC1DBE9` (`Language_Id`), 
    CONSTRAINT `FK8B4876F3AEC1DBE9` FOREIGN KEY (`Language_Id`) REFERENCES `Language` (`Id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 | 
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

mysql> select * from Language; 
+----+------+----------+---------+------------+ 
| Id | Code | Name  | Variant | Country_Id | 
+----+------+----------+---------+------------+ 
| 1 | en | English |   |  235 | 
| 2 | ro | Romanian |   |  181 | 
+----+------+----------+---------+------------+ 
2 rows in set (0.00 sec) 

mysql> select * from Language_Phrases; 
Empty set (0.00 sec) 

mysql> INSERT INTO Language_Phrases (Language_Id, Label, Phrase) VALUES (1, 'exampleLabel', 'Some phrase'); 
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`dev`.`language_phrases`, CONSTRAINT `FK8B4876F3AEC1DBE9` FOREIGN KEY (`Language_Id`) REFERENCES `Language` (`Id`)) 
mysql> 

UPDATE:删除和重建数据库几次后,我做了show engine innodb status上述失败的插入操作后,得到了这个令人惊讶的结果。父语言表未找到!这似乎很奇怪...有什么想法?

------------------------ 
LATEST FOREIGN KEY ERROR 
------------------------ 
110406 9:55:49 Transaction: 
TRANSACTION CA3B, ACTIVE 0 sec, OS thread id 4494462976 inserting 
mysql tables in use 1, locked 1 
1 lock struct(s), heap size 376, 0 row lock(s) 
MySQL thread id 25, query id 50720 localhost root update 
INSERT INTO Language_Phrases (Language_Id, Label, Phrase) VALUES (1, 'exampleLabel', 'Some phrase') 
Foreign key constraint fails for table `dev`.`language_phrases`: 
, 
    CONSTRAINT `FK8B4876F3AEC1DBE9` FOREIGN KEY (`Language_Id`) REFERENCES `Language` (`Id`) 
Trying to add to index `PRIMARY` tuple: 
DATA TUPLE: 5 fields; 
0: len 4; hex 80000001; asc  ;; 
1: len 17; hex 747970654d69736d617463682e79656172; asc exampleLabel;; 
2: len 6; hex 00000000ca3b; asc  ;;; 
3: len 7; hex 00000000000000; asc  ;; 
4: len 21; hex 59656172206d7573742062652061206e756d626572; asc Some phrase;; 

But the parent table `dev`.`Language` 
or its .ibd file does not currently exist! 

更新2:原来,这简直是在MySQL中的大规模错误。显然最新版本的MySQL在mac os X 10.6下不能正常工作(也许早期版本?)。降级到5.5.8似乎工作。非常令人惊讶。

+1

有没有到这个错误被提到一个链接?我有同样的问题(mysql5.5和osx10.6),并希望阅读更多。 – 2011-04-13 14:58:46

+0

我没有方便的链接,我们在MySQL论坛中找到了它们,并且还有一个错误报告。 – 2011-04-14 17:32:19

+0

有这个完全相同的问题,感谢张贴这个家伙。这在过去几天一直令我疯狂。 – 2011-09-26 15:32:32

回答

8

这确实出现了一个错误,因为MySQL的5.5.9在Mac OS X介绍: http://bugs.mysql.com/bug.php?id=60309

它被标记为固定在5.5.13(月发行31),并在发行说明中提到: http://dev.mysql.com/doc/refman/5.5/en/news-5-5-13.html

另外,还有在我已经验证了5.5.10及以下转载的bug报告中列出的解决方法:

 

[20 Mar 11:29] Harald Neiss 

I also received a new MBP and reinstalled MySQL (mysql-5.5.10-osx10.6-x86_64). Finally I 
came across the same problem as described above. So here is the query result and what I 
did to solve it. 

mysql> show variables like 'lower%'; 
+------------------------+-------+ 
| Variable_name   | Value | 
+------------------------+-------+ 
| lower_case_file_system | ON | 
| lower_case_table_names | 2  | 
+------------------------+-------+ 
2 rows in set (0.00 sec) 

Dropped database, created the file /etc/my.cnf with the following content: 

[mysqld] 
lower_case_table_names=1 

Restarted the MySQL daemon and repeated the query: 

mysql> show variables like 'lower%'; 
+------------------------+-------+ 
| Variable_name   | Value | 
+------------------------+-------+ 
| lower_case_file_system | ON | 
| lower_case_table_names | 1  | 
+------------------------+-------+ 
2 rows in set (0.00 sec) 

I recreated the tables and everything works fine. 

+0

谢谢!我会检查出最新版本的mysql! – 2011-06-07 07:44:09

+0

升级到OS X Lion后,再次出现此问题。上面提到的解决方法这次似乎并不奏效,所以我不得不升级MySQL。通过[homebrew](https://github.com/mxcl/homebrew)安装的版本5.5.14可以满足您的需求! – penfold 2011-08-15 01:23:50

0

检查Language_Phrases (Language_Id)LanguageId)的数字类型属性

both should be either UNSIGNED ZEROFILL or SIGNED

+0

如何检查或设置它们是否已签名或未签名? – 2011-04-06 13:53:36

+0

他们都是'int(11)'根据'describe' – 2011-04-06 13:54:08

+0

转到'phpmyadmin'并检查两者..可能是属性名称中的一些空间? – diEcho 2011-04-07 04:27:26

0

*的MySQL> INSERT INTO Language_Phrases(LANGUAGE_ID,标签,词组)VALUES(1, 'exampleLabel', '部分短语'); ERROR 1452(23000):不能添加或更新子行:... *

您正在试图插入为LANGUAGE_ID,但表语言具有财产AUTO_INCREMENT = 。在这种情况下,你应该使用3或更高。

+0

我给出了语言的输出,其中包括2行(这就是auto_increment = 3的原因) – 2011-04-07 14:30:53

+0

尝试重新创建FK;有同样的错误 - http://forums.mysql.com/read.php?135407929,407929#msg-407929 – Devart 2011-04-08 06:56:07

+0

删除并重新创建外键不会修复错误。但有趣的线程。看起来MySQL的最后3个版本都很糟糕,至少在Mac OS X 10.6上。降级到MySQL 5.5.8为我们工作,以及该线程... – 2011-04-09 04:14:51

1

并不奇怪恕我直言。我在MySQL中发现了很多错误。例如,使用Where子句(如WHERE some_tinyint_column = 0)运行查询将不会产生任何数据,但将该子句重写为“WHERE(NOT some_tinyint_column = 1)”会产生结果。经过一番研究,我发现这是一个本来应该修复的bug,但是在我使用的版本中,bug仍然存在。结论:在MySQL中绝对没有意义的事情时,我通常认为它是安全的,可以假设它是一个bug,并开始研究这些信息。

0

今天我有同样的错误。就我而言,我已经使用脚本重新创建了一些包含所有记录的表格。事实上,我已经意识到我的表格之间的“引擎”类型是不同的:一个是MyISAM,第二个(FK的引用)是InnoDB。我已将所有表格更改为InnoDB,现在一切正常。

这个脚本会产生一个更新脚本文件(Reference

mysql -u DB_USER -pDB_PASSWORD --default-character-set=utf8 DATABASE_NAME -e "SELECT CONCAT('ALTER TABLE ', table_name, ' ENGINE=InnoDB;') AS sql_statements FROM information_schema.tables AS tb WHERE table_schema = database() AND ENGINE = 'MyISAM' AND TABLE_TYPE = 'BASE TABLE' ORDER BY table_name DESC;" > ./alter_InnoDb.sql 

您必须删除的第一行“alter_InnoDb.sql”,包含文本“sql_statements”行。

之后,您可以在数据库中执行脚本来更正此错误:

mysql -u DB_USER -pDB_PASSWORD --default-character-set=utf8 DATABASE_NAME < ./ alter_InnoDb.sql