我必须在 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 进行了尝试,但没有成功。

有任何想法吗?

有帮助吗?

解决方案

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;

然后一切都应该正常工作。

其他提示

虽然与MySQL工作台和MySQL 5.5.27的工作,我也遇到了类似的问题。在我的情况的问题是用INT类型的字段。错误地在一个表中它是INT无符号和在引用表是INT。

根据MySQL版本,你可能需要先创建table1.field1索引。

一的答案在这里建议,以禁止外键的完整性检查。这是一个糟糕的想法。有两种可能的罪魁祸首在这里:

  • 数据类型之间的不匹配所引用的主要关键和引用外键
  • 指数。任何外国键你指数必须不空

<强>另一个提示:

甚至当你的数据类型似乎是相同的 - 在我的情况都列有VARCHAR(50) - 这是不够的。

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

又一原因,尽管略微类似于他人:我指的是这被证明具有MyISAM引擎的表,而不是InnoDB的

如果你打错了参照表的名称

MySQL也将抛出此错误。我把我的头发过一段时间,直到我意识到我错过了在foreign key (column1) references mistyped_table(column1)

一个选项(视情况而定)。将禁用MySQL的完整性校验:

SET FOREIGN_KEY_CHECKS = 0;

如果实在不行,试试这个:

外键的名称是一个已经存在的密钥的副本。检查你的外键的名称是数据库中是唯一的。只要你的键名的末尾添加一些随机字符来测试这一点。

在我的情况下,一个表是使用上还不存在其它表的外键约束。这是发生由于大量生成文件,所以还不如我会一直预期的那样明显。

在的情况下有人仍然有这个问题,我尝试了所有的上述解决方案(除了SET FOREIGN_KEY_CHECKS)并没有什么工作。问题是,当你引用的第一个表,有些数据库是区分关于表的名称非常敏感。我觉得这很奇怪,因为我从来没有见过这之前在MySQL,Oracle和现在这事对我来说就MariaDB的。

例如:

创建表,如果不存在CADASTRO_MAQUINAS( ID VARCHAR(16), 主键(id) );

创建表,如果不存在INFOS( Id_Maquina VARCHAR(16)NOT NULL, 约束FK_infos_cadastro_maquinas外键(Id_Maquina)引用CADASTRO_MAQUINAS(同上) );

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

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

我对我的表的一个类似的错误。当被选中列排序规则是不同的,这一次得手改变两列以相同的排序规则类型。

读取最建议的解决方案的后这里。我想这可能是有益的,如果我只列出了所有可能抛出这个错误的可能性。

1,检查柱的CASE 2,检查柱整理 3,检查是否有该列(唯一的,首要的)两个表中创建的密钥

在我来说,我在表中的一个上了年纪的表定义MyISAM和很明显,我无法从另一个表让外国钥匙。也许这帮助别人。

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

Field Type
Field Collation
Table Engine

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

您还可以尝试引用您的外键组合键时遇到了同样的错误。

例如:

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

在这种情况下,它作为它们出现在制品表的主键定义中使用的article_id和类型字段中定义FK在非常相同的顺序很重要。

在我的情况很可能是一个错误的服务器删除表具有相同的名称。 丢弃整个shcema和重新创建它解决了这个问题。

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

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

如果您正在使用MySQL工作台,你会得到这个错误的关系表有可能是你速战速决:删除它,让MySQL工作台重新给你。然后复制SQL。固定我错误号150的问题。

我试图使用一个外键引用一个非唯一的领域得到这个错误。 (其显然是不允许的)

当我有这个问题,那是因为我已经设定的ID在第一个表被unsigned而在第二个表的外键不是。使它们二者unsigned固定对我来说。

始终首先创建主/父表,然后创建你的细节/子表。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top