MySQL:使用FK错误创建表(错误150)

时间:2009-07-05 22:54:43

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

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

使用文件>出口>正向工程师SQL CREATE Script ... 它为我输出一个很好的大文件,我要求的所有设置。我切换到MySQL GUI Tools(专门用于查询浏览器)并加载此脚本(请注意,我将从另一个官方MySQL工具开始)。但是,当我尝试实际执行此文件时,我一遍又一遍地得到相同的错误

  

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

4 个答案:

答案 0 :(得分:40)

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

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 ,

因此,您尝试使用表INT中的state字段引用brand字段(表TINYINTlocation)。我认为这是它抱怨的错误。不确定它是如何出现的,或者为什么归零FOREIGN_KEY_CHECKS并不能阻止MySQL诊断错误,但如果你修复了这种类型不匹配会怎样?

答案 1 :(得分:9)

对于查看此主题的其他人来说,有很多原因导致您收到此错误:

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

MySQL Foreign Key Errors and Errno 150

答案 2 :(得分:0)

刚检查了@juacala的回答。但是没有帮助我。当我发现麻烦来源时,我发送了@ELIACOM的消息。

  

我正在阅读这个很好的解决方案来源,但我的问题不是   不客气。我试图在一个指向a的INNODB表中添加一个FK   MyISAM中的PK。将MyIsam设置为INNODB之后就可以了。一世   在意识到之前检查了你的整个清单。欢呼声。

答案 3 :(得分:-2)

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