MySQL自引用外键

16

我目前正在尝试在MySQL中创建一个自引用表,但似乎无法在表本身上创建外键,我收到了一个MySQL错误:

Error Code: 1005. Can't create table 'biological classification' (errno: 150)

这是我的代码:
# Table creation
DROP TABLE IF EXISTS `biological classification`;
CREATE TABLE `biological classification` (
  `idBC` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `idParent` int(11) DEFAULT NULL,
  `type` varchar(45) DEFAULT NULL,
  `value` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`idBC`),
  UNIQUE KEY `idnew_table_UNIQUE` (`idBC`),
  CONSTRAINT `SelfKey` FOREIGN KEY (`idParent`) REFERENCES `biological classification` (`idBC`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=latin1 COMMENT='A table that contains the Biological Classification of anima';

# insert into table
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (1,NULL,'Class','Mammalia');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (2,1,'Genus','Giraffa');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (3,2,'Species','Giraffa camelopardalis');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (5,1,'Genus','Panthera');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (6,1,'Genus','Loxodonta');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (7,5,'Species','Panthera leo');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (8,5,'Species','Panthera tigris');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (9,6,'Species','Loxodonta africana');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (10,1,'Class','Marsupialia');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (11,10,'Genus','Macropus');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (12,11,'Species','Macropus rufus');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (13,1,'Genus','Sarcophilus');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (14,13,'Species','Sarcophilus harrisii');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (15,10,'Genus','Didelphis');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (16,15,'Species','Didelphis virginiana');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (17,NULL,'Class','Aves');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (18,17,'Genus','Aquila');
INSERT INTO `biological classification` (`idBC`,`idParent`,`type`,`value`) VALUES (19,18,'Species','Aquila chrysaetos');
2个回答

20

将列idParent的类型更改为int(10) unsigned,以便它与引用列idBC具有相同的类型。

DROP TABLE IF EXISTS `biological classification`;
CREATE TABLE `biological classification` (
  `idBC` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `idParent` int(10) unsigned DEFAULT NULL,
  `type` varchar(45) DEFAULT NULL,
  `value` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`idBC`),
  UNIQUE KEY `idnew_table_UNIQUE` (`idBC`),
  CONSTRAINT `SelfKey` FOREIGN KEY (`idParent`) REFERENCES `biological classification` (`idBC`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=latin1 COMMENT='A table that contains the Biological Classification of anima';

3
我知道这已经有一段时间了,但是对于谷歌搜索者来说:我遇到了类似的情况。我有几个表,其中所有id字段都是int(11)类型的。它们中没有一个是“unsigned”,所以它们都很相似。然而,MySQL拒绝创建自引用表。其他表已经创建成功。阅读了这篇页面后,我给它们全部添加了“unsigned”,然后一切正常了。我认为,尽管所有id字段完全相同,但如果你将其中一些设置为“autoincrement”,它们可能会被接受为“unsigned”。可能这就是我的问题所在。谢谢。 - Malkocoglu

13

为什么会把表名中间加空格?

可以将其命名为 biological_classification,使用下划线而非空格。

然后让这两列使用相同的数据类型,要么都是int(10)或都是int(11),并且它们都是signed或都是unsigned


不是int(10)或int(11)需要对齐,而是有符号和无符号的需要对齐。 - Johan
15
因为在数据库中,表名和列名是需要经常使用的标识符,而空格在这些标识符中被视为特殊字符,容易导致错误。此外,在使用SQL语句时,需要将表名和列名用引号括起来,如果包含空格会影响代码的可读性和编写效率。因此,最好避免在表名中使用空格。希望我的回答对你有所帮助,不要担心,我们都曾是新手。 - Skeen
7
这段话主要谈论了提高可读性和舒适度的通用良好实践。若在名称中有空格,常常需要处理括号等其他事项,使得问题变得比实际情况更加复杂。不仅在 SQL 中,避免在标识符中使用空格是一种通用的良好实践。 - Fabian Barney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接