MySQL。无法创建表,错误号150。

68

我需要在MySQL中创建两个表的数据库,但是脚本出现了错误号150(外键问题)。我已经仔细检查了两个表中的外键字段,但是没有发现任何错误。

以下是脚本:

 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';

 DROP SCHEMA IF EXISTS `testdb`;
 CREATE SCHEMA IF NOT EXISTS `testdb` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
 USE `testdb`;

 DROP TABLE IF EXISTS `testdb`.`table1` ;

 CREATE  TABLE IF NOT EXISTS `testdb`.`table1` (
   `id` INT UNSIGNED NOT NULL ,
   `field1` VARCHAR(50) NULL ,
   PRIMARY KEY (`id`) )

 ENGINE = InnoDB;


 DROP TABLE IF EXISTS `testdb`.`table2` ;

 CREATE  TABLE IF NOT EXISTS `testdb`.`table2` (
   `id` INT NOT NULL AUTO_INCREMENT ,
   `field1` VARCHAR(50) NULL ,
   `date` DATE NULL ,
   `cnt` INT NULL ,
   PRIMARY KEY (`id`) ,
   INDEX `FK_table2_table1` (`field1` ASC) ,
   CONSTRAINT `FK_table2_table1`
   FOREIGN KEY (`field1`)
   REFERENCES `testdb`.`table1` (`field1` )
   ON DELETE NO ACTION
   ON UPDATE NO ACTION)

 ENGINE = InnoDB;

 SET SQL_MODE=@OLD_SQL_MODE;
 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

我已经在Windows和Ubuntu上尝试了不同版本的MySQL,但没有成功。

有什么想法吗?


9
我尝试创建一个与另一个还不存在的表具有FK约束的表时,也遇到了这个错误。这是一个容易解决的问题,但由于错误消息完全无用,因此变得非常困难。 - Cerin
2
对于从谷歌搜索到这里的人,如果您在外键表名称上打错了字,也会出现此错误。 - D_C
22个回答

54

table1.field1没有定义索引。

需要在field1上放置FOREIGN KEY约束。

使用以下代码:

 CREATE  TABLE IF NOT EXISTS `testdb`.`table1` (
   `id` INT UNSIGNED NOT NULL ,
   `field1` VARCHAR(50) NULL ,
   KEY ix_table1_field1 (field1),
   PRIMARY KEY (`id`) )
 ENGINE = InnoDB;

然后一切都应该按预期工作。


18
虽然在这种情况下不适用,但如果您尝试为非空列添加外键约束并将其设置为null时,您将收到相同的错误消息。 - John Zumbrum

49
在使用MySQL Workbench和MySQL 5.5.27时,我遇到了类似的问题。在我的情况下,问题出在INT类型字段上。错误地,在一个表中它是INT UNSIGNED,在引用表中它是INT。

13

根据MySQL的版本,您可能需要先在table1.field1上创建一个索引。


8

这里的一个回答建议禁用外键完整性检查。这是一个糟糕的主意。有两个可能的罪魁祸首:

  • 引用的主键和外键引用之间存在数据类型不匹配
  • 索引。您索引的任何外键都必须为 NOT NULL

NOT NULL 参数在我的 Mysql 5.5 上不适用。 - Déjà vu

6

另一个提示:

即使您的数据类型似乎相同-在我的情况下,两列都有VARCHAR(50) - 但这还不够。

您还需要确保两个列具有相同的COLLATION


5

根据情况,一种选择是禁用MySQL完整性检查:

SET FOREIGN_KEY_CHECKS = 0;

5

还有另一个原因,虽然与其他原因略微相似:我引用的表格实际上使用的是 MyISAM 引擎,而不是 InnoDB 引擎。


5

如果您在引用表的名称时打错了,MySQL也会抛出此错误。我曾经因为没有意识到在foreign key (column1) references mistyped_table(column1)中漏掉了一个字母而苦恼了一段时间。


在某些情况下,大小写(表名)很重要 - 在某些情况下不重要。例如,我的脚本在OSX上的mysql上运行良好,但在Linux上我遇到了errno:150问题。大小写是我的问题。 - prule
同样地,我曾经有一个FOREIGN KEY (user_id) REFERENCES user(id) ON DELETE CASCADE,但是 user 表中没有 id 字段——它被称为 user_id!所以在上面的语句中,我把 user(id) 改成了 user(user_id),这样宇宙中的一切都恢复正常了...暂时。 - elimisteve

1

我在试图使用外键引用非唯一字段时遇到了此错误。(显然是不允许的)


1
如果一切都不起作用,尝试以下方法:
外键名称与已存在的键重复。请确保您的外键名称在数据库中是唯一的。只需在键名末尾添加几个随机字符以进行测试即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接