此表中的外键约束有啥问题?

Posted

技术标签:

【中文标题】此表中的外键约束有啥问题?【英文标题】:What's wrong with the Foreign Key Constraint in this table?此表中的外键约束有什么问题? 【发布时间】:2011-10-05 21:14:56 【问题描述】:

mysql 5.1.59 在创建表时抛出错误:

CREATE  TABLE IF NOT EXISTS `genre` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `abv` CHAR(3) CHARACTER SET 'latin1' COLLATE 'latin1_bin' NULL DEFAULT NULL ,
  `name` VARCHAR(80) NOT NULL DEFAULT '' ,
  `parent_id` INT NULL DEFAULT NULL ,
  PRIMARY KEY (`id`) ,
  INDEX `fk_genre_genre1` (`parent_id` ASC) ,
  CONSTRAINT `fk_genre_genre1`
    FOREIGN KEY (`parent_id` )
    REFERENCES `genre` (`id` )
    ON DELETE SET NULL
    ON UPDATE CASCADE)
ENGINE = InnoDB;

由 MySQLWorkbench 5.2.33 生成。错误信息是:

第 __ 行出现错误 1005 (HY000):无法创建表 'mydb.genre' (errno: 150)

这个创建表有什么问题?

The manual says:

如果 MySQL 从 CREATE TABLE 语句中报告错误号 1005, 并且错误消息是指错误150,表创建失败 因为没有正确形成外键约束。

它还说允许对同一个表的外键引用:

InnoDB 支持表中的外键引用。在这些情况下, “子表记录”实际上是指 同一张桌子。

我想要的关系是一个不可识别的父子关系,以表示流派和子流派的层次结构。流派不必有父级,因此 parent_id 可以为空。

MySQLWorkbench 设置以下可能是相关的:

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';

【问题讨论】:

SHOW ENGINE InnoDB STATUS 收到该错误后立即。通常它会给你真正的错误信息。 +1 一个格式精美的问题,包含所有相关信息。 这是一个方便的提示,derobert,谢谢! 【参考方案1】:

您的专栏idint unsigned;你的专栏parent_idint。那些不匹配。解决方法是将parent_id 也改为int unsigned

如果你运行 SHOW ENGINE InnoDB STATUS 我发表了评论,你会看到:

11005 17:18:38 Error in foreign key constraint of table test/genre:

    FOREIGN KEY (`parent_id` )
    REFERENCES `genre` (`id` )
    ON DELETE SET NULL
    ON UPDATE CASCADE)
ENGINE = InnoDB:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
for correct foreign key definition.

注意“表中的列类型与引用的表不匹配”部分。

【讨论】:

这很容易解决!谢谢。【参考方案2】:

这两个字段的类型不同。

CREATE  TABLE IF NOT EXISTS `genre` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,  <<-- unsigned int
  ..
  ..
  `parent_id` INT NULL DEFAULT NULL ,        <<-- signed int
  PRIMARY KEY (`id`) ,                   ***** not the same!!!!
  ....

【讨论】:

超级!谢谢!我给德罗伯特打勾只是因为他早了一分钟。 @fsb,不,他不是!-) 16 分钟前的我,15 分钟前的德罗伯特。仍然 derobert 与节目引擎的东西有很好的联系,所以他的接受是值得的。【参考方案3】:

id 未签名,但 parent_id 并非未签名。

【讨论】:

【参考方案4】:

字段的类型必须相同。 id 是无符号的,而 parent_id 不是

【讨论】:

以上是关于此表中的外键约束有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以将一个表中的主键引用为超过 2 个表的外键约束?

MYSQL外键约束

从表 2 中的外键约束中删除表 1 中确实具有主键的记录

Oracle外键需要建索引吗?

数据库中的外键约束

补12.关于mysql的外键约束