为什么MySQL不接受我的外键?

时间:2013-09-16 13:43:55

标签: mysql foreign-keys foreign-key-relationship

我有26张彼此非常依赖的表格。我创建了每个表,然后通过MySQL Workbench在数据库中执行。然后我构建模型,我链接这些表创建外键。我将其导出回元数据,现在我已经拥有了应用程序创建的适当外部数据的完整代码表,所以我没有犯错。

但是当我把文件放在我的服务器上由phpMyAdmin运行时,我得到一个150错误,但没有指明它在哪里。我用Google搜索了它,但每个案例都不同,我的是FK不是自动增量字段,而是我创建的一个名为UT的字符串字段,当我创建一行时它具有时间单位。

CREATE  TABLE IF NOT EXISTS `eduardo8_plataforma`.`aplicativo` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT ,
  `ut` VARCHAR(20) NOT NULL ,
  `nome` VARCHAR(99) NOT NULL ,
  `ver` VARCHAR(20) NULL DEFAULT NULL ,
  `descr` VARCHAR(254) NULL DEFAULT NULL ,
  `tag` VARCHAR(254) NULL DEFAULT NULL ,
  `url` VARCHAR(254) NULL DEFAULT NULL ,
  `cad` VARCHAR(20) NULL DEFAULT NULL ,
  `obj` TEXT NULL DEFAULT NULL ,
  `tab` VARCHAR(254) NULL DEFAULT NULL ,
  `dbn` VARCHAR(254) NULL DEFAULT NULL ,
  `dbu` VARCHAR(254) NULL DEFAULT NULL ,
  `dbs` VARCHAR(254) NULL DEFAULT NULL ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `nome` (`nome` ASC) ,
  UNIQUE INDEX `ut_UNIQUE` (`ut` ASC) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_swedish_ci;

CREATE  TABLE IF NOT EXISTS `eduardo8_plataforma`.`modulo` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT ,
  `ut` VARCHAR(20) NOT NULL ,
  `app` VARCHAR(20) NULL DEFAULT NULL ,
  `lic` VARCHAR(20) NULL DEFAULT NULL ,
  `tipo` VARCHAR(20) NULL DEFAULT NULL ,
  `nome` VARCHAR(99) NOT NULL ,
  `classe` VARCHAR(99) NOT NULL ,
  `obj` TEXT NULL DEFAULT NULL ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `ut_UNIQUE` (`ut` ASC) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_swedish_ci;

CREATE  TABLE IF NOT EXISTS `eduardo8_plataforma`.`modulo_app` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT ,
  `ut` VARCHAR(20) NOT NULL ,
  `app` VARCHAR(20) NOT NULL ,
  `modulo` VARCHAR(20) NOT NULL ,
  PRIMARY KEY (`id`) ,
  INDEX `fk_modulo_app_modulo1` (`modulo` ASC) ,
  INDEX `fk_modulo_app_aplicativo1` (`app` ASC) ,
  UNIQUE INDEX `ut_UNIQUE` (`ut` ASC) ,
  CONSTRAINT `fk_modulo_app_modulo1`
    FOREIGN KEY (`modulo` )
    REFERENCES `eduardo8_plataforma`.`modulo` (`ut` )
    ON DELETE CASCADE
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_modulo_app_aplicativo1`
    FOREIGN KEY (`app` )
    REFERENCES `eduardo8_plataforma`.`aplicativo` (`ut` )
    ON DELETE CASCADE
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_swedish_ci;

有效的表格(答案后):

CREATE  TABLE IF NOT EXISTS `eduardo8_plataforma`.`modulo_app` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT ,
  `ut` VARCHAR(20) CHARACTER SET 'utf8' COLLATE 'utf8_swedish_ci' UNIQUE NOT NULL ,
  `app` VARCHAR(20) CHARACTER SET 'utf8' COLLATE 'utf8_swedish_ci' NOT NULL ,
  `modulo` VARCHAR(20) CHARACTER SET 'utf8' COLLATE 'utf8_swedish_ci' NOT NULL ,
  PRIMARY KEY (`id`) ,
  INDEX `fk_modulo_app_modulo1` (`modulo` ASC) ,
  INDEX `fk_modulo_app_aplicativo1` (`app` ASC) ,
  UNIQUE INDEX `ut_UNIQUE` (`ut` ASC) ,
  CONSTRAINT `fk_modulo_app_modulo1`
    FOREIGN KEY (`modulo` )
    REFERENCES `eduardo8_plataforma`.`modulo` (`ut` )
    ON DELETE CASCADE
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_modulo_app_aplicativo1`
    FOREIGN KEY (`app` )
    REFERENCES `eduardo8_plataforma`.`aplicativo` (`ut` )
    ON DELETE CASCADE
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_swedish_ci;

2 个答案:

答案 0 :(得分:4)

您需要在外键之前移动CREATE INDEX子句,因为外键不能引用非索引字段。

答案 1 :(得分:2)

简短的说法是外键应该引用候选键列。也就是说,它应该引用一个声明为

的列
  • 主键,或
  • not null unique。

如果引用非唯一的列,标准SQL dbms将引发错误。 MySQL也应该,但它不会。

Mysql Docs

  

。 。 。系统不强制要求引用的列   是UNIQUE或声明为NOT NULL。外键的处理   对非唯一键或包含NULL值的键的引用不是   为UPDATE或DELETE CASCADE等操作定义良好。你是   建议使用仅引用UNIQUE的外键(包括   PRIMARY)和NOT NULL键。

如果您需要来自其他表的非唯一数据,请将其加入查询中,或者在视图中加入。