错误No 150 mySQL

时间:2010-06-03 14:59:45

标签: mysql mysql-error-1005

这让我很生气 - 当我尝试在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 个答案:

答案 0 :(得分:4)

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

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

  

外键约束错误   表测试/批准:FOREIGN KEY   (rev_idrev_page)参考   revisionrev_idrev_page),
  约束FK_approval_user外国人   KEY(user_id)参考user   (user_id))ENGINE = InnoDB DEFAULT   CHARSET = latin1:找不到索引   在引用的表中所在的位置   引用的列显示为第一列   表中的列或列类型   和引用的表不匹配   约束。

答案 1 :(得分:2)

更新:我一定是失明的:

你的create table失败的原因是因为你的“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

寻找smth。喜欢“最后的外键错误” 不幸的是,错误信息在大多数情况下并不是很直观。既然你说类型都是一样的我猜它可能是以下错误:

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

答案 2 :(得分: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`)

答案 3 :(得分:0)

显示innodb状态

这个cmd有很多帮助