MySQL外键错误1005 errno 150
我正在用MySQL Workbench做一个小的数据库。 我有一个名为“Immobili”的主表,它有一个由四列(Comune,Via,Civico,Immobile)组成的主键。
现在,我还有另外三个表,它们具有相同的主键(Comune,Via,Civico,Immobile),但是这些字段也被引用到表Immobili中。
第一个问题:我可以创build一个也是外键的主键吗?
第二个问题:当我尝试导出更改时,它说:在服务器中执行SQL脚本
# ERROR: Error 1005: Can't create table 'dbimmobili.condoni' (errno: 150) CREATE TABLE IF NOT EXISTS `dbimmobili`.`Condoni` ( `ComuneImmobile` VARCHAR(50) NOT NULL , `ViaImmobile` VARCHAR(50) NOT NULL , `CivicoImmobile` VARCHAR(5) NOT NULL , `InternoImmobile` VARCHAR(3) NOT NULL , `ProtocolloNumero` VARCHAR(15) NULL , `DataRichiestaSanatoria` DATE NULL , `DataSanatoria` DATE NULL , `SullePartiEsclusive` TINYINT(1) NULL , `SullePartiComuni` TINYINT(1) NULL , `OblazioneInEuro` DOUBLE NULL , `TecnicoOblazione` VARCHAR(45) NULL , `TelefonoTecnico` VARCHAR(15) NULL , INDEX `ComuneImmobile` (`ComuneImmobile` ASC) , INDEX `ViaImmobile` (`ViaImmobile` ASC) , INDEX `CivicoImmobile` (`CivicoImmobile` ASC) , INDEX `InternoImmobile` (`InternoImmobile` ASC) , PRIMARY KEY (`ComuneImmobile`, `ViaImmobile`, `CivicoImmobile`, `InternoImmobile`) , CONSTRAINT `ComuneImmobile` FOREIGN KEY (`ComuneImmobile` ) REFERENCES `dbimmobili`.`Immobile` (`ComuneImmobile` ) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `ViaImmobile` FOREIGN KEY (`ViaImmobile` ) REFERENCES `dbimmobili`.`Immobile` (`ViaImmobile` ) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `CivicoImmobile` FOREIGN KEY (`CivicoImmobile` ) REFERENCES `dbimmobili`.`Immobile` (`CivicoImmobile` ) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `InternoImmobile` FOREIGN KEY (`InternoImmobile` ) REFERENCES `dbimmobili`.`Immobile` (`InternoImmobile` ) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB
显示引擎状态:
表dbimmobili / valutazionimercato的外键约束错误:
无法在引用表中find引用列作为第一列显示的索引,或者表中的列和引用表不匹配约束。 请注意,ENUM和SET的内部存储types在使用> = InnoDB-4.1.12创build的表中进行了更改,旧表中的这些列不能被新表中的这些列引用。
我在哪里做错了?
创build外键约束时,MySQL在引用表和引用表上都需要一个可用的索引。 引用表上的索引是自动创build的(如果不存在),但引用表上的索引需要手动创build( Source )。 你的似乎失踪了。
testing用例:
CREATE TABLE tbl_a ( id int PRIMARY KEY, some_other_id int, value int ) ENGINE=INNODB; Query OK, 0 rows affected (0.10 sec) CREATE TABLE tbl_b ( id int PRIMARY KEY, a_id int, FOREIGN KEY (a_id) REFERENCES tbl_a (some_other_id) ) ENGINE=INNODB; ERROR 1005 (HY000): Can't create table 'e.tbl_b' (errno: 150)
但是,如果我们在some_other_id
上添加索引:
CREATE INDEX ix_some_id ON tbl_a (some_other_id); Query OK, 0 rows affected (0.11 sec) Records: 0 Duplicates: 0 Warnings: 0 CREATE TABLE tbl_b ( id int PRIMARY KEY, a_id int, FOREIGN KEY (a_id) REFERENCES tbl_a (some_other_id) ) ENGINE=INNODB; Query OK, 0 rows affected (0.06 sec)
在大多数情况下这通常不是问题,因为引用字段通常是被引用表的主键,并且主键被自动索引。
仔细检查外键是否与本表中的字段具有完全相同的types。 例如,它们都应该是Integer(10)或Varchar(8),即使是字符数也是如此。
我意识到这是一个旧post,但它在Google中名列前茅,所以我join了我想要解决的问题。 如果你有多种表types(例如MyISAM和InnoDB),你也会得到这个错误。 在这种情况下,InnoDB是默认的表types,但是一个表需要全文search,所以它被迁移到了MyISAM。 在这种情况下,您不能在引用MyISAM表的InnoDB表中创build一个外键。
如果你的键是一个CHAR / VARCHAR或types的东西,另一个可能的问题是不同的sorting规则。 检查字符集是否相同。
我有这个错误,发现在我的情况下的错误的原因。 我仍然回答这个旧post,因为它在Google上排名很高。
我想要链接的这两列的variables都是整数,但是其中一个整数没有被检查。 简单地取消检查,解决了我的错误。
我得到一个相同的错误。 我find了解决scheme,我已经在主表中创build主键为BIGINT UNSIGNED,并在第二个表中将其声明为只有BIGINT的外键。
当我在第二个表中声明我的外键为BIGINT UNSIGED时,一切正常,甚至不需要创build任何索引。
所以这是主键和外键之间的数据types不匹配:)
我有完全相同的问题,但解决我的问题是完全不同的。 我在数据库的其他地方有一个同名的外键。 这导致了错误1005。
将我的外键重命名为更具体的情况解决了这个问题。
- 确保两个表都使用相同的引擎types。
- 确保你正在索引的字段具有相同的types和长度。
我还没有声望投票史蒂夫的build议,但它解决了我的问题。
在我的情况下,我收到这个错误,因为两个表使用不同的数据库引擎创build – 一个是Innodb和另一个MyISAM。
您可以使用以下方式更改数据库types:ALTER TABLE t ENGINE = MYISAM;
@see http://dev.mysql.com/doc/refman/5.1/en/storage-engine-setting.html
在我的情况下,错误是由于referencing
表是MyISAM
,其中referring
表是InnoDB
。
从MyISAM to InnoDB
Converted
表引擎为我解决了这个问题。
ALTER TABLE table_name ENGINE=InnoDB;
这不是你的具体情况,但值得注意的是,如果你试图引用表中的某些字段,而不是表的整个主键,则可能会发生此错误。 显然这是不允许的。
如果任何人有看似良好的FK / PK关系的这个错误,并且你使用了可视化工具,请尝试删除有问题的fk列并在工具中重新添加它们。 我一直在得到这个错误,直到我重新解决了解决问题的连接。
当主键有两列时,它们组成一个组合主键,因此必须确保在被引用的表中有两列相同的数据types。
对我而言,我试图将子表中的常规索引字段与父表中的主键相匹配,默认情况下,某些MySQL前端GUI(如Sequel Pro)将主键设置为无符号,因此您必须确保子表字段也是无符号的(除非这些字段可能包含负整数,然后确保它们都是有符号的)。
MySQL是臭名昭着的,特别是关于外键和触发器。 我现在正在调整一个这样的数据库,并遇到这个问题。 这不是自明或直觉,所以在这里:
除了检查关系中要引用的两列是否具有相同的数据types外,还必须确保引用的表中的列是索引。 如果您正在使用MySQL Workbench,请select“列”旁边的“索引”选项卡,并确保外键引用的列是索引。 如果没有,创build一个,命名它有意义的,并给它的types“INDEX”。
一个好的做法是清理关系中涉及的表格,以确保以前的尝试不会创build您不想要或不需要的索引。
我希望它有帮助,一些MySQL错误是疯狂跟踪。
创build表时,请注意CHARSET和COLLATE参数。 就外键问题而言:
CREATE TABLE yourTableName ( .... .... ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
在我的情况下,我不能用FOREIGN KEY引用创build表。 首先我得到了错误代码1005几乎没有说什么。 然后我添加了COLLATE ,最后是抱怨CHARSET的错误信息。
Error Code: 1253. COLLATION 'utf8_unicode_ci' is not valid for CHARACTER SET 'latin1'
在那次更正之后,我的问题解决了。
第一个问题:我可以创build一个也是外键的主键吗?
是。 实际上,对于MySQL工作台,我习惯于只使用主键作为外键。 真的减less了收到的随机错误,就像问题中提到的错误:150。
#错误:错误1005:无法创build表'dbimmobili.condoni'(errno:150)
这对索引有一些帮助,或者更具体地说,MySQL工作台是如何解释和处理它们的。 如果你在模型中改变很多(例如,外键,索引,列顺序),那么在同一个正向工程操作中, 特别是在另一端已经有一个数据库的时候,它确实会变得很混乱。 例如,我不认为自动创build索引删除外键后自动删除。
这是我做了什么来解决您收到的错误。 请注意,这似乎很麻烦,但与我花在使用其他方法上的时间相比,事实并非如此。
1.使查找表中的所有外键主键(1到1中的1)。
在我的情况下,这涉及到更改id作为用户名tkl_users中的用户名,用户名和公司在tbl_companies,用户名和公司和联系人在tbl_company_contacts。 这是一个为多个用户input多个公司联系人的应用程序,允许其他用户联系人重叠和隐藏。
2.删除所有图关系和所有不是主键的表索引。
这修复了MySQL工作台错误导致的大部分索引问题。
3.如果你从头到尾这样做,把模式放在服务器上,这样mysql工作台就不会对现有的索引感到困惑,并且在模型中缺less这个索引(问题是引起bby索引和外键关系,而不是索引本身)。
这减less了很多DB,服务器和Mysql工作台所做的大量决定。 这些关于如何转发工程的决定是复杂而智能的,但不完善。
4.现在,我认为这回到了原来的方式(通常在devise之后,没有一个步进过程太快)。 我仍然拥有所有桌子,但在这个阶段他们很干净。 现在你只是:
首先,正向工程师只是为了确保表(无关系)按预期工作。
按照关系链,通过主键,从最顶级的表开始(我是我的情况tbl_users tbl_companies)。 每次关系之后,总是进行正向工程以确保它运行 ,然后保存模型并closures,然后对模型进行反向工程,以确保它完成。 这可以让你快速隔离出现的问题,在我的情况下留下索引使用旧的删除外键(发生了2-3次)。
而泰达,回到你需要的地方。