8

刚刚在 mac os x 10.6 上安装了 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> 

更新:多次删除并重新创建数据库后,我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 似乎可行。非常令人惊讶。

4

6 回答 6

9

这似乎是自 Mac OS X 上的 MySQL 5.5.9 以来引入的一个错误: http ://bugs.mysql.com/bug.php?id=60309

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

或者,我在 5.5.10 上验证并在下面复制的错误报告中列出了一种解决方法:

[3 月 20 日 11:29] 哈拉尔德·奈斯

我还收到了新的 MBP 并重新安装了 MySQL (mysql-5.5.10-osx10.6-x86_64)。最后我
遇到了与上述相同的问题。所以这是查询结果和我
确实解决了它。

mysql> 显示像'lower%'这样的变量;
+------------------------+--------+
| 变量名 | 价值 |
+------------------------+--------+
| 小写文件系统 | 开 |
| 小写表名 | 2 |
+------------------------+--------+
2 行(0.00 秒)

删除数据库,创建文件 /etc/my.cnf,内容如下:

[mysqld]
lower_case_table_names=1

重新启动 MySQL 守护程序并重复查询:

mysql> 显示像'lower%'这样的变量;
+------------------------+--------+
| 变量名 | 价值 |
+------------------------+--------+
| 小写文件系统 | 开 |
| 小写表名 | 1 |
+------------------------+--------+
2 行(0.00 秒)

我重新创建了表格,一切正常。

于 2011-06-07T07:32:44.897 回答
1

恕我直言,这并不奇怪。我在 MySQL 中发现了许多错误。例如,使用 where 子句(如“WHERE some_tinyint_column = 0”)运行查询将不会产生任何数据,但将子句重写为“WHERE (NOT some_tinyint_column = 1)”会产生结果。经过一番研究,我发现这是一个应该修复的错误,但在我使用的版本中,错误仍然存​​在。

结论:当某些东西在 MySQL 中完全没有意义时,我通常会认为它是一个错误并开始研究这些方面的信息是安全的。

于 2013-02-01T19:21:55.730 回答
1

我也面临同样的问题,并没有找到任何解决我的问题的解决方案。因此,由于多种原因,可能会出现此问题。我只是试图将尽可能多的这些原因和解决方案放在一个地方,并提供帮助我解决这个问题的修复程序。我希望这对将来的人有所帮助。

1) 由Penfold提供- 表名区分大小写
2) 父子表中的引擎不匹配
3) 父子表中的字符集不匹配
4) Parent(Id) 和 Child(Patent_Id :两者必须具有完全相同的数据类型(也签名/Unsigned)
5) InnoDB 丢失表但表存在 -请在此处找到解决方案

SQL 查询(显示引擎 InnoDB 状态)给出此错误(其 .ibd 文件当前不存在!) Blockquote

6)很少有旧版本的mysql有这个bug。Bug#60196 , Bug#60309
7) 这对我有用(如果上面的一切看起来都很好,你可能需要这个)- 从子表中删除外键并再次添加约束。如果它也失败,则删除父表并再次创建它,在此之前您需要从所有子表中删除外键。这是最后可能的事情。
进一步阅读:
https ://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_lower_case_table_names

于 2020-01-09T18:20:48.417 回答
0

检查 Language_Phrases (Language_Id)Language( Id)的数值类型属性

两者都应该是UNSIGNED ZEROFILLSIGNED

于 2011-04-06T13:34:48.317 回答
0

*mysql> INSERT INTO Language_Phrases (Language_Id, Label, Phrase) VALUES (1, 'exampleLabel', 'Some phrase'); 错误 1452 (23000):无法添加或更新子行:...*

您正在尝试将1作为 Language_Id 插入,但表 Language 具有属性 AUTO_INCREMENT= 3。在这种情况下,您应该使用 3 或更高。

于 2011-04-07T11:53:30.753 回答
0

我今天有同样的错误。就我而言,我使用脚本重新创建了一些包含所有记录的表。

事实上,我已经意识到我的表之间的“引擎”类型是不同的:一个是 MyISAM,第二个(FK 的引用)是 InnoDB。我已将所有表更改为 InnoDB,现在一切正常。

该脚本将生成一个更新脚本文件(参考

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
于 2013-09-27T19:09:44.367 回答