MySQL:创建带有 FK 错误的表 (errno 150)

Posted

技术标签:

【中文标题】MySQL:创建带有 FK 错误的表 (errno 150)【英文标题】:MySQL: Creating table with FK error (errno 150) 【发布时间】:2010-11-08 06:31:53 【问题描述】:

我已经使用mysql Workbench 创建了一个模型,现在正尝试将它安装到 mysql 服务器。

使用 File > Export > Forward Engineer SQL CREATE Script... 它会为我输出一个不错的大文件,其中包含我要求的所有设置。我切换到MySQL GUI Tools(特别是查询浏览器)并加载此脚本(请注意,我将从一个官方 MySQL 工具转换为另一个)。但是,当我尝试实际执行此文件时,我一遍又一遍地收到相同的错误

SQLSTATE[HY000]:一般错误:1005 无法创建表 './srs_dev/location.frm' (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';

-- -----------------------------------------------------
-- Table `state`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `state` ;

CREATE  TABLE IF NOT EXISTS `state` (
  `state_id` INT NOT NULL AUTO_INCREMENT ,
  `iso_3166_2_code` VARCHAR(2) NOT NULL ,
  `name` VARCHAR(60) NOT NULL ,
  PRIMARY KEY (`state_id`) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `brand`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `brand` ;

CREATE  TABLE IF NOT EXISTS `brand` (
  `brand_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `name` VARCHAR(45) NOT NULL ,
  `domain` VARCHAR(45) NOT NULL ,
  `manager_name` VARCHAR(100) NULL ,
  `manager_email` VARCHAR(255) NULL ,
  PRIMARY KEY (`brand_id`) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `location`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `location` ;

CREATE  TABLE IF NOT EXISTS `location` (
  `location_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `name` VARCHAR(255) NOT NULL ,
  `address_line_1` VARCHAR(255) NULL ,
  `address_line_2` VARCHAR(255) NULL ,
  `city` VARCHAR(100) NULL ,
  `state_id` TINYINT UNSIGNED NULL DEFAULT NULL ,
  `postal_code` VARCHAR(10) NULL ,
  `phone_number` VARCHAR(20) NULL ,
  `fax_number` VARCHAR(20) NULL ,
  `lat` DECIMAL(9,6) NOT NULL ,
  `lng` DECIMAL(9,6) NOT NULL ,
  `contact_url` VARCHAR(255) NULL ,
  `brand_id` TINYINT UNSIGNED NOT NULL ,
  `summer_hours` VARCHAR(255) NULL ,
  `winter_hours` VARCHAR(255) NULL ,
  `after_hours_emergency` VARCHAR(255) NULL ,
  `image_file_name` VARCHAR(100) NULL ,
  `manager_name` VARCHAR(100) NULL ,
  `manager_email` VARCHAR(255) NULL ,
  `created_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  PRIMARY KEY (`location_id`) ,
  CONSTRAINT `fk_location_state`
    FOREIGN KEY (`state_id` )
    REFERENCES `state` (`state_id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_location_brand`
    FOREIGN KEY (`brand_id` )
    REFERENCES `brand` (`brand_id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

CREATE INDEX `fk_location_state` ON `location` (`state_id` ASC) ;

CREATE INDEX `fk_location_brand` ON `location` (`brand_id` ASC) ;

CREATE INDEX `idx_lat` ON `location` (`lat` ASC) ;

CREATE INDEX `idx_lng` ON `location` (`lng` ASC) ;

在我看来还可以。我猜测可能是查询浏览器有问题,所以我把这个文件放在服务器上并尝试这样加载它

] mysql -u admin -p -D dbname < path/to/create_file.sql

我得到同样的错误。所以我开始用谷歌搜索这个问题,发现各种帐户都在谈论 InnoDB 样式表的错误,这些表使用外键失败,修复方法是添加“SET FOREIGN_KEY_CHECKS=0;”到 SQL 脚本。好吧,正如您所看到的,这已经是 MySQL Workbench 吐出的文件的一部分。

那么,我的问题是,当我在做我认为我应该做的事情时,为什么这不起作用?

版本信息:

MySQL:5.0.45

GUI 工具:1.2.17 工作台:5.0.30

【问题讨论】:

虽然你的SQL不是这样,但同样的错误也是由于表之间没有唯一的外键名造成的。 【参考方案1】:

外键中字段的类型必须与它们引用的列的类型相同。你有以下(截图):

CREATE  TABLE IF NOT EXISTS `state` (
  `state_id` INT NOT NULL AUTO_INCREMENT ,
...
CREATE  TABLE IF NOT EXISTS `brand` (
  `brand_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
...
CREATE  TABLE IF NOT EXISTS `location` (
...
  `state_id` TINYINT UNSIGNED NULL DEFAULT NULL ,
...
  `brand_id` TINYINT UNSIGNED NOT NULL ,

所以您尝试使用表location 中的TINYINT 字段来引用INT 字段(在表statebrand 中)。我认为这就是它抱怨的错误。不确定它最初是如何出现的,或者为什么将 FOREIGN_KEY_CHECKS 归零并不能阻止 MySQL 诊断错误,但是如果你修复了这种类型不匹配会发生什么?

【讨论】:

好的,嗯...哈哈。哇,好尴尬我忙于寻找实际关系中的问题,以至于我没有检查列本身。感谢您的第二双眼睛! 哇!混合“INT”和“INT UNSIGNED”时也会发生这种情况。是的,这是我的错;但是,MySQL Workbench 需要对此发出警告!【参考方案2】:

对于查看此线程的其他人,您可能会收到此错误的原因有很多:

有关 errno 150、errno 121 和其他 MySQL 外键错误的完整列表,请参阅以下链接:

MySQL Foreign Key Errors and Errno 150

【讨论】:

好的,谢谢!顺便说一句,喜欢 xkcd 漫画。我可以在很大程度上联系起来!干杯。 这是我需要的答案。我的问题是 MyISAM 而不是 InnoDB。【参考方案3】:

刚刚检查了@juacala 的答案。但没有帮助我。这是我在找到问题根源时发送给@ELIACOM 的消息。:

我正在阅读这个伟大的解决方案来源,但我的问题不是 解决的。我试图在指向一个 INNODB 表中添加一个 FK 在 MyISAM 中进行 PK。将 MyIsam 设置为 INNODB 后,它起作用了。一世 在意识到这一点之前检查了你的整个清单。干杯。

【讨论】:

那里有,但是对于某些版本,外键添加会默默地失败。它在“其他外键错误”下的列表中排名第二【参考方案4】:

我有同样的问题。不知何故,我没有注意到将 auto_increment 值设置为表 id。 也许它可以帮助某人。

【讨论】:

AUTO_INCREMENT 与否,对外键有效性没有影响。

以上是关于MySQL:创建带有 FK 错误的表 (errno 150)的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 错误:#1005 - 无法创建表 (errno: 150) 当我尝试创建超过 1 个 FK

MySQL删除数据库时的错误(errno: 39)

创建带有外键错误号的 sql 表:150

Mysql:无法创建表 errno 150

外键和 MySQL 错误

EntityFramework尝试创建指向同一个表的多个链接,FK Constraint错误