我正在使用MySQL Workbench做一个小型数据库。我有一个名为“Immobili”的主表,它有一个由四列组成的主键:( Comune,Via,Civico,Immobile)。
现在,我还有另外三个表,它们具有相同的主键(Comune,Via,Civico,Immobile),但这些字段也引用了表Immobili。
第一个问题:我可以制作一个也是外键的主键吗?
第二个问题:当我尝试导出更改时,它说: 在服务器
中执行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的外键约束出错:
在引用的表中找不到引用列作为第一列的索引, 表中的列或列,并且引用的表与约束不匹配。请注意,在使用> =创建的表中,ENUM和SET的内部存储类型已更改 InnoDB-4.1.12和旧表中的此类列不能被这些列引用 在新表中。
我做错了什么?
答案 0 :(得分:50)
创建外键约束时,MySQL需要在引用表和引用表上都有可用的索引。如果不存在引用表,则会自动创建引用表,但需要手动创建引用表上的索引(Source)。你的似乎不见了。
测试用例:
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)
在大多数情况下,这通常不是问题,因为引用的字段通常是引用表的主键,主键是自动索引的。
答案 1 :(得分:30)
仔细检查外键的类型与此表中的字段完全相同。例如,两者都应该是Integer(10)或Varchar(8),甚至是字符数。
答案 2 :(得分:15)
我意识到这是一个老帖子,但它在谷歌中排名很高,所以我添加了我想出的问题。如果您有多种表格类型(例如MyISAM和InnoDB),您也会收到此错误。在这种情况下,InnoDB是默认的表类型,但是一个表需要全文搜索,因此它被迁移到MyISAM。在这种情况下,您无法在InnoDB表中创建引用MyISAM表的外键。
答案 3 :(得分:9)
如果您的密钥是CHAR / VARCHAR或类似的东西,另一个可能的问题是不同的整理。检查字符集是否相同。
答案 4 :(得分:6)
我遇到了这个错误,并在我的案例中找到了错误的原因。 我还在回答这个老帖子,因为它在谷歌上排名很高。
我想要链接的两个列的变量都是整数,但其中一个整数已经未签名'检查。只需取消选中即可修复错误。
答案 5 :(得分:5)
我得到了同样的错误。我发现我在主表中创建主键的解决方案为BIGINT UNSIGNED,并在第二个表中将其声明为外键,仅作为BIGINT。
当我在第二个表中将我的外键声明为BIGINT UNSIGED时,一切正常,甚至不需要创建任何索引。
因此,主键和外键之间的数据类型不匹配:)
答案 6 :(得分:4)
我有完全相同的问题,但我的问题的解决方案完全不同。我在数据库的其他地方有一个同名的外键。这导致错误1005.
将我的外键重命名为更适合该情况的内容解决了这个问题。
答案 7 :(得分:3)
答案 8 :(得分:3)
在我的情况下,错误是由于referencing
表格为MyISAM
,而referring
表格为InnoDB
。
Converted
的 MyISAM to InnoDB
表引擎为我解决了这个问题。
ALTER TABLE table_name ENGINE=InnoDB;
答案 9 :(得分:1)
我还没有声名鹊起Steve的建议,但它解决了我的问题。
在我的情况下,我收到此错误,因为使用不同数据库引擎创建的两个表 - 一个是Innodb,另一个是MyISAM。
您可以使用以下命令更改数据库类型:ALTER TABLE t ENGINE = MYISAM;
@see http://dev.mysql.com/doc/refman/5.1/en/storage-engine-setting.html
答案 10 :(得分:1)
创建表时,请注意 CHARSET 和 COLLATE 参数。 就FOREIGN KEY 问题而言:
CREATE TABLE yourTableName (
....
....
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
在我的情况下,我无法使用FOREIGN KEY引用创建表。首先我得到了错误代码1005,几乎没有说什么。然后我添加了COLLATE ,最后错误消息抱怨CHARSET。
Error Code: 1253. COLLATION 'utf8_unicode_ci' is not valid for CHARACTER SET 'latin1'
经过纠正后,我的问题得到了解决。
答案 11 :(得分:0)
如果有任何人在看似格式良好的FK / PK关系中出现此错误并且您使用了可视化工具,请尝试删除有问题的fk列并在工具中重新添加它们。我不断得到这个错误,直到我重新清除了解决问题的连接。
答案 12 :(得分:0)
如果主键有2列,则它们构成复合主键,因此您必须确保在被引用的表中还有2列相同数据类型。
答案 13 :(得分:0)
这不是您的具体情况,但值得注意的是,如果您尝试引用表中不是该表的整个主键的某些字段,则会发生此错误。显然这是不允许的。
答案 14 :(得分:0)
对我来说,我试图将子表中的常规索引字段与父表中的主键进行匹配,默认情况下,一些像Sequel Pro这样的MySQL前端GUI将主键设置为unsigned,因此您有确保子表字段也是无符号的(除非这些字段可能包含负的int,然后确保它们都已签名)。
答案 15 :(得分:0)
除了检查要在关系中引用的两列是否具有相同的数据类型之外,还必须确保要引用的表上的列是索引。如果您使用的是MySQL Workbench,请选择选项卡" Indexes"紧靠"列"并确保外键引用的列是索引。如果没有,请创建一个,将其命名为有意义的内容,并为其指定类型" INDEX"。
一个好的做法是清理关系中涉及的表格,以确保以前的尝试不会创建您不想要或不需要的索引。
我希望它有所帮助,一些MySQL错误令人抓狂。
答案 16 :(得分:0)
第一个问题:我可以制作同时也是外键的主键吗?
是。事实上,对于MySQL工作台,我已经习惯只使用主键作为外键。真正减少收到的随机错误,如问题中所述的错误:150。
#ERROR:错误1005:无法创建表'dbimmobili.condoni'(错误号:150)
这确实与索引有关,或者更具体地说,MySQL工作台如何解释和使用它们。如果你在同一个正向工程操作中改变模型中的很多东西(例如外键,索引,col命令),那真的很困惑,,特别是如果另一端已有数据库。例如,我不认为自动创建的索引在删除外键后会自动删除。
以下是我为解决您收到的错误所做的工作。注意,它似乎很麻烦,但与我使用其他方法花费的时间相比,它不是。
<强> 1。在查找表中创建所有外键主键(1到1中的1)。
在我的情况下,这包括将tb更改为tbl_users中的用户名,tbl_companies中的用户名和公司,以及tbl_company_contacts中的用户名AND公司AND联系人。这是一个供多个用户输入多个公司联系人的应用程序,允许重叠和隐藏其他用户联系人。
<强> 2。删除所有不是主键的图表关系和所有表索引。
这解决了大多数真正由错误的MySQL工作台引起的索引问题。
第3。如果你从头到尾这样做,请将模式放在服务器上,这样mysql工作台就不会对现有索引感到困惑,并且在模型中没有关闭(问题是由于bby索引和外键关系,而不是索引)。 强>
这减少了DB,服务器和Mysql工作台必须做出的很多决定。这些关于如何推进工程设计的决定既复杂又聪明,但并不完美。
<强> 4。现在,我认为这回到原点(通常在没有阶梯式处理的情况下设计得太快)。我仍然拥有所有的桌子,但在这个阶段他们很干净。现在你只是:
首先,正向工程师只是为了确保表格(没有关系)按预期工作。
通过主键关注关系链,从最顶层的表开始(我的情况是tbl_users到tbl_companies)。在每次关系之后,始终转发工程师确保运行,然后保存模型并关闭,然后对模型进行反向工程以确保 。这允许您快速隔离出现的问题,在我的情况下留下旧的删除外键使用的索引(发生2-3次)。
tadda,回到你需要的地方。