14

所以我试图向我的一个表中添加一个新的外键:

 ALTER TABLE `UserTransactions`.`ExpenseBackTransactions` 
   ADD CONSTRAINT `FK_EBTx_CustomAccountID`
   FOREIGN KEY (`CustomAccountID` )
   REFERENCES `UserTransactions`.`CustomAccounts` (`CustomAccountID`)
   ON DELETE NO ACTION
   ON UPDATE NO ACTION,
   ADD INDEX `FK_EBTx_CustomAccountID` (`CustomAccountID` ASC) ;

我不断收到以下错误:

Error Code: 1005
Can't create table './UserTransactions/#sql-187a_29.frm' (errno: 150)

过去我对这个表和其他表进行了相当多的更改,这是我第一次遇到这个问题。任何想法是什么原因造成的?

更新

我的SHOW INNODB STATUS错误:

------------------------
LATEST FOREIGN KEY ERROR
------------------------
110525 15:56:36 Error in foreign key constraint of table UserTransactions/#sql-187a_2c:

  FOREIGN KEY (`CustomAccountID` )
  REFERENCES `UserTransactions`.`CustomAccounts` (`CustomAccountID` )
  ON DELETE NO ACTION
  ON UPDATE NO ACTION
, ADD INDEX `FK_EBTx_CustomAccountID` (`CustomAccountID` ASC):
Cannot resolve table name close to:
 (`CustomAccountID` )
  ON DELETE NO ACTION
  ON UPDATE NO ACTION
, ADD INDEX `FK_EBTx_CustomAccountID` (`CustomAccountID` ASC)
4

3 回答 3

28

这里有一个很好的清单

以下是人们报告的可怕 errno 150 的已知原因的运行列表:

  1. 两个关键字段类型和/或大小不完全匹配。例如,如果一个是 INT(10),则关键字段也需要是 INT(10),而不是 INT(11) 或 TINYINT。您可能希望使用 SHOW CREATE TABLE 确认字段大小,因为查询浏览器有时会直观地显示 INT(10) 和 INT(11) 的 INTEGER。您还应该检查一个未签名,另一个未签名。它们都需要完全相同。(有关签名与未签名的更多信息,请点击此处)。
  2. 您尝试引用的关键字段之一没有索引和/或不是主键。如果关系中的某个字段不是主键,则必须为该字段创建索引。(感谢 Venkatesh 和 Erichero 以及终端不连贯的提示)
  3. 外键名称是已经存在的键的副本。检查您的外键名称在您的数据库中是唯一的。只需在密钥名称的末尾添加一些随机字符即可进行测试。(感谢尼尔斯的这个提示)
  4. 您的一个或两个表是 MyISAM 表。为了使用外键,表必须都是 InnoDB。(实际上,如果两个表都是 MyISAM,那么您将不会收到错误消息——它只是不会创建密钥。)在查询浏览器中,您可以指定表类型。
  5. 您已指定级联 ON DELETE SET NULL,但相关的关键字段设置为 NOT NULL。您可以通过更改级联或将字段设置为允许 NULL 值来解决此问题。(感谢 Sammy 和 J Jammin)
  6. 确保 Charset 和 Collat​​e 选项在表级别以及键列的单个字段级别都相同。(感谢 FRR 的提示)
  7. 您的外键列上有一个默认值(即 default=0)(感谢 Omar 的提示)
  8. 关系中的一个字段是组合(复合)键的一部分,并且没有自己的单独索引。即使该字段有一个索引作为复合键的一部分,您也必须仅为该键字段创建一个单独的索引才能在约束中使用它。(感谢 Alex 的提示)
  9. 您的 ALTER 语句中有语法错误,或者您在关系中输入错误的字段名称之一(感谢 Christian & Mateo 的提示)
  10. 您的外键名称超过了 64 个字符的最大长度。(感谢 Nyleta 的提示)
于 2011-05-25T21:58:59.683 回答
3

以我的经验,errno: 150通常表示FOREIGN KEY键表和相关表中列的数据类型不相同。确保CustomAccounts.CustomAccountIDExpenseBackTransactions.CustomAccountID是完全相同的类型,包括UNSIGNED它是否适用。

如果这没有帮助,请发布SHOW CREATE TABLE ExpenseBackTransactions;SHOW CREATE TABLE CustomAccounts;

于 2011-05-25T21:55:07.717 回答
0

Catch 22. Foreign keys need indexes. MySQL doesn't order this query so that the index exists at the time it does it foreign key checks. Thus, first create the index, then add the foreign key in 2 separate queries.

于 2011-05-25T22:04:27.153 回答