68

我必须在 MySQL 中创建一个包含两个表的数据库,但脚本失败并出现 errno 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 进行了尝试,但没有成功。

有任何想法吗?

4

22 回答 22

54

table1.field1没有定义索引。

需要对 进行FOREIGN KEY约束field1

有了这个:

 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;

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

于 2009-11-17T14:46:18.353 回答
49

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

于 2013-05-10T20:26:21.060 回答
13

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

于 2009-11-17T14:45:29.487 回答
8

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

  • 引用的主键和引用的外键之间的数据类型不匹配
  • 指数。您索引的任何外键都必须不是 NULL
于 2013-06-24T15:40:13.370 回答
6

另一个提示:

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

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

于 2013-05-22T07:48:01.753 回答
5

一个选项(视情况而定)是禁用 MySQL 完整性检查:

SET FOREIGN_KEY_CHECKS = 0;
于 2013-02-05T14:12:18.093 回答
5

还有另一个原因,尽管与其他原因有些相似:我指的是一个表,它原来具有 MyISAM 引擎,而不是 InnoDB。

于 2013-11-18T08:40:28.803 回答
5

如果您输错了引用表的名称,MySQL 也会抛出此错误。我把头发拉了一会儿,直到我意识到我错过了一封信foreign key (column1) references mistyped_table(column1)

于 2013-12-31T00:21:31.047 回答
1

如果没有任何效果,试试这个:

外键名称是已经存在的键的副本。检查您的外键名称在您的数据库中是唯一的。只需在密钥名称的末尾添加一些随机字符即可进行测试。

于 2012-10-26T05:26:39.827 回答
1

尝试使用外键引用非唯一字段时出现此错误。(这显然是不允许的)

于 2016-08-16T12:05:51.893 回答
0

始终首先创建主/父表,然后创建您的详细信息/子表。

于 2013-02-01T04:40:20.117 回答
0

在我的例子中,一个表在另一个不存在的表上使用外键约束。这是由于生成文件很大,所以它不像我预期的那么明显。

于 2013-02-09T05:58:06.313 回答
0

如果有人仍然对此有问题,我尝试了上述所有解决方案(SET FOREIGN_KEY_CHECKS 除外),但没有任何效果。问题是当您引用第一个表时,某些数据库对表名区分大小写。我认为这很奇怪,因为我以前从未在 MySQL、Oracle 上看到过这种情况,而现在这发生在 MariaDB 上。

例如:

如果不存在则创建表 CADASTRO_MAQUINAS (Id VARCHAR(16), Primary Key (Id));

如果不存在则创建表 INFOS ( Id_Maquina VARCHAR(16) NOT NULL, CONSTRAINT FK_infos_cadastro_maquinas 外键 (Id_Maquina) 引用 CADASTRO_MAQUINAS(Id) );

如果我尝试使用 cadastro_maquinas(小写)而不是 CADASTRO_MAQUINAS 创建第二个表,我将收到此错误。

于 2013-02-21T12:52:19.673 回答
0

我正在使用MySQL workBench. 问题是你不能使用相同的foreign key name,他们需要unique。因此,如果多个表将引用相同的外键,则每次都必须unique给出一个名称。

于 2013-04-06T05:49:00.553 回答
0

我在我的一张桌子上遇到了类似的错误。检查时,列排序规则不同,一旦将两列更改为相同的排序规则类型,它就起作用了。

在阅读了此处建议的大部分解决方案后。我只是认为如果我列出所有可能引发此错误的可能性可能会有所帮助。

1、检查列的CASE 2、检查列的COLLATION 3、检查是否在两个表中都为该列创建了一个键(Unique、Primary)

于 2013-06-27T12:29:22.707 回答
0

就我而言,我在其中一个表中获得了旧表定义 MyISAM,显然我无法从另一个表中为其创建外键。也许这对某人有帮助。

所以这可能是因为两个数据库/字段定义之间的不一致尝试检查:

Field Type
Field Collation
Table Engine
于 2013-12-13T11:44:14.130 回答
0

对我来说,问题CONSTRAINT在于在CREATE TABLE查询中使用。

于 2014-06-12T19:19:49.060 回答
0

尝试在外键中引用复合键时,您也可能会遇到相同的错误。

例如:

CREATE TABLE `article` (
  `id` int(10) unsigned NOT NULL,
  `type` enum('X','Y','Z') NOT NULL,
  PRIMARY KEY (`id`,`type`)
) ENGINE InnoDB;

CREATE TABLE `t1` (
  `user_id` int(10) unsigned NOT NULL,
  `type` enum('X','Y','Z') NOT NULL,
  `article_id` int(10) unsigned NOT NULL,
  CONSTRAINT `user_access_article_ibfk_2` FOREIGN KEY (`article_id`, `type`) REFERENCES `article` (`id`, `type`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB

在这种情况下,在 FK 定义中使用 article_id 和 type 字段的顺序与它们在文章表 PRIMARY KEY 定义中出现的顺序完全相同,这一点很重要。

于 2014-12-29T19:40:01.330 回答
0

在我的情况下,可能是服务器错误删除了同名的表。删除整个 shcema 并重新创建它解决了这个问题。

于 2015-03-21T11:13:32.397 回答
0

在非常奇怪的情况下,您的数据库可能会损坏。就我而言,我的表上没有任何外键,唯一的重命名表或更改引擎有帮助。

原来innoDB坏了,见:https ://dba.stackexchange.com/questions/86853/1025-error-on-rename-of-table-errno-150-table-was-deleted-while-tried-to- a?lq=1

于 2015-06-25T11:25:26.493 回答
0

如果您正在使用 mysql 工作台并且您在关系表中遇到此错误,则可能有一个快速修复方法:只需删除它并让 mysql 工作台为您重新创建它。然后复制sql。修复了我的 errno 150 问题。

于 2016-03-28T11:28:08.923 回答
0

当我遇到这个问题时,是因为我将第一个表中的 id 设置为,unsigned而第二个表中的外键没有。让他们都unsigned为我修好了。

于 2017-12-23T15:17:19.440 回答