3

这让我汗流浃背 - 当我尝试在 mySQL 中创建表时,我收到错误 150。我翻遍了论坛,没有用。该语句使用外键约束 - 两个表都是 InnoDB,所有相关列都具有相同的数据类型,并且两个表具有相同的字符集和排序规则。这是被引用表的 CREATE TABLE 和原始 CREATE TABLE 语句。有任何想法吗?

新表:

CREATE TABLE `approval` (
  `rev_id` int(10) UNSIGNED NOT NULL,
  `rev_page` int(10) UNSIGNED NOT NULL,
  `user_id` int(10) UNSIGNED NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY  (`rev_id`,`rev_page`,`user_id`),
  KEY `FK_approval_user` (`user_id`),
  CONSTRAINT `FK_approval_revision` FOREIGN KEY (`rev_id`, `rev_page`) REFERENCES `revision` (`rev_id`, `rev_page`),
  CONSTRAINT `FK_approval_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

参考表:

CREATE TABLE `revision` (
  `rev_id` int(10) unsigned NOT NULL auto_increment,
  `rev_page` int(10) unsigned NOT NULL,
  `rev_text_id` int(10) unsigned NOT NULL,
  `rev_comment` tinyblob NOT NULL,
  `rev_user` int(10) unsigned NOT NULL default '0',
  `rev_user_text` varbinary(255) NOT NULL default '',
  `rev_timestamp` binary(14) NOT NULL default '\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
  `rev_minor_edit` tinyint(3) unsigned NOT NULL default '0',
  `rev_deleted` tinyint(3) unsigned NOT NULL default '0',
  `rev_len` int(10) unsigned default NULL,
  `rev_parent_id` int(10) unsigned default NULL,
  PRIMARY KEY  (`rev_id`),
  UNIQUE KEY `rev_page_id` (`rev_page`,`rev_id`),
  KEY `rev_timestamp` (`rev_timestamp`),
  KEY `page_timestamp` (`rev_page`,`rev_timestamp`),
  KEY `user_timestamp` (`rev_user`,`rev_timestamp`),
  KEY `usertext_timestamp` (`rev_user_text`,`rev_timestamp`)
) ENGINE=InnoDB AUTO_INCREMENT=4904 DEFAULT CHARSET=binary MAX_ROWS=10000000 AVG_ROW_LENGTH=1024;
4

4 回答 4

4

此错误通常与外键限制有关。执行show innodb status并查找LATEST FOREIGN KEY ERROR部分以获得更具体的解释。

这是我在创建第二个表时得到的:

表测试/批准的外键约束错误:FOREIGN KEY ( rev_id, rev_page) REFERENCES revision( rev_id, rev_page),
CONSTRAINT FK_approval_userFOREIGN KEY ( user_id) REFERENCES user ( user_id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1: 在被引用的表中找不到被引用列的索引显示为第一列,或者表中的列类型与引用的表不匹配约束。

于 2010-06-03T15:10:44.860 回答
2

更新:我一定是盲人:

创建表失败的原因是因为您的“rev_page_id”键顺序错误(innodb 要求键与外键的顺序相同:

CREATE TABLE `revision` (
  `rev_id` int(10) unsigned NOT NULL auto_increment,
  ....
  `rev_parent_id` int(10) unsigned default NULL,
  PRIMARY KEY  (`rev_id`),
  -- wrong:
  -- UNIQUE KEY `rev_page_id` (`rev_page`,`rev_id`), 
  -- better:
  UNIQUE KEY `rev_page_id` (`rev_id`, `rev_page`),
  ....

请忽略以下建议:


尝试

SHOW ENGINE INNODB STATUS

找东西。像“LAST INNODB FOREIGN KEY ERROR” 不幸的是,错误信息在大多数情况下都不是很直观。既然你说类型都是一样的,我猜这可能是以下错误:

  • FK 名称已存在(FK 名称在整个数据库中必须是唯一的)。确实,它们对于整个 mysql 实例必须是唯一的,但在内部 innodb 将数据库名称添加到外键名称(FK_approval_user 内部称为 yourdbname#FK_approval_user)

更新:

看起来您缺少“FK_approval_revision”的密钥

应该是这样的:

CREATE TABLE `approval` (
  `rev_id` int(10) UNSIGNED NOT NULL,
  `rev_page` int(10) UNSIGNED NOT NULL,
  `user_id` int(10) UNSIGNED NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY  (`rev_id`,`rev_page`,`user_id`),
  KEY `FK_approval_user` (`user_id`),
  KEY `FK_approval_revision` (`rev_id`, `rev_page`),
  CONSTRAINT `FK_approval_revision` FOREIGN KEY (`rev_id`, `rev_page`) REFERENCES `revision` (`rev_id`, `rev_page`),
  CONSTRAINT `FK_approval_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
于 2010-06-03T15:09:52.950 回答
1

如果您更改约束定义中列的顺序,它将起作用:

FOREIGN KEY (`rev_page`,`rev_id`) REFERENCES `revision` (`rev_page`,`rev_id`)

您的原始查询不起作用,因为字段的顺序必须与唯一索引中的相同。但是,将 rev_page 列添加到约束是多余的(revision.rev_id + revision.rev_page 在没有唯一约束的情况下是 100% 唯一的,因为 revision.rev_id 本身是唯一的)。所以你不需要唯一的键 (revision.rev_id + revision.rev_page),如果你改变你的约束会更好

FOREIGN KEY (`rev_id`) REFERENCES `revision` (`rev_id`)
于 2010-06-03T15:12:18.290 回答
0

显示 innodb 状态

这个 cmd 有很大帮助

于 2011-09-16T11:01:15.300 回答