在MySQL中,外键添加失败,错误代码为1005,编号为150

时间:2011-05-25 21:51:27

标签: mysql foreign-keys mysql-error-1005

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

 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)

3 个答案:

答案 0 :(得分:27)

nice checklist here

  

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

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

答案 1 :(得分:3)

根据我的经验,errno: 150通常表示密钥表和相关表中FOREIGN KEY列的数据类型不相同。请确保CustomAccounts.CustomAccountIDExpenseBackTransactions.CustomAccountID完全相同,如果适用,则包括UNSIGNED

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

答案 2 :(得分:0)

Catch 22.外键需要索引。 MySQL不对此查询进行排序,以便在进行外键检查时存在索引。因此,首先创建索引,然后在2个单独的查询中添加外键。