繁体   English   中英

MySQL 外键错误 1005 errno 150 主键作为外键

[英]MySQL Foreign Key Error 1005 errno 150 primary key as foreign key

我正在使用 MySQL Workbench 制作一个小型数据库。 我有一个名为“Immobili”的主表,它有一个由四列组成的主键:(Comune、Via、Civico、Immobile)。

我还有其他三个表,它们具有相同的主键(Comune、Via、Civico、Immobile),但这些字段也引用到表 Immobili。

第一个问题:我可以制作一个也是外键的主键吗?

第二个问题:当我尝试导出更改时,它说:

Executing SQL script in server

# 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 的外键约束错误:

无法在被引用表中找到被引用列显示为第一列的索引,或者表中的列类型与被引用表的约束不匹配。 请注意,在>= InnoDB-4.1.12创建的表中,ENUM和SET的内部存储类型发生了变化,旧表中的此类列不能被新表中的此类列引用。

我哪里做错了?

创建外键约束时,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)

在大多数情况下这通常不是问题,因为被引用的字段通常是被引用表的主键,并且主键会自动建立索引。

仔细检查外键的类型是否与您在此表中获得的字段完全相同。 例如,两者都应该是 Integer(10) 或 Varchar(8),甚至是字符数。

我意识到这是一篇旧帖子,但它在谷歌中排名很高,所以我正在添加我为我的问题找到的东西。 如果您有混合的表类型(例如 MyISAM 和 InnoDB),您也会收到此错误。 在这种情况下,InnoDB 是默认的表类型,但是有一个表需要全文搜索,因此它被迁移到了 MyISAM。 在这种情况下,您无法在引用 MyISAM 表的 InnoDB 表中创建外键。

如果您的键是 CHAR/VARCHAR 或某种类型的东西,另一个可能的问题是不同的排序规则。 检查字符集是否相同。

我遇到了这个错误,并在我的案例中找到了错误的原因。 我仍在回答这个旧帖子,因为它在 Google 上的排名相当高。

我想链接的两列的变量都是整数,但其中一个整数已选中“无符号”。 只需取消选中即可修复我的错误。

我遇到了同样的错误。 我发现我在主表中将主键创建为 BIGINT UNSIGNED 并将其声明为第二个表中的外键的解决方案只有 BIGINT。

当我在第二个表中将我的外键声明为 BIGINT UNSIGED 时,一切正常,甚至不需要创建任何索引。

所以这是主键和外键之间的数据类型不匹配:)

我遇到了完全相同的问题,但解决我的问题的方法完全不同。 我在数据库的其他地方有一个同名的外键。 这导致了错误 1005。

将我的外键重命名为更具体的情况解决了这个问题。

  1. 确保两个表都使用相同的引擎类型。
  2. 确保您正在编制索引的字段具有相同的类型和长度。

在我的情况下,错误是由于referencing表是MyISAMreferring表是InnoDB

Converted表引擎从MyISAM to InnoDB Converted MyISAM to InnoDB为我解决了这个问题。

ALTER TABLE table_name ENGINE=InnoDB;

我还没有投票支持史蒂夫的建议的声誉,但它解决了我的问题。

就我而言,我收到此错误是因为使用不同的数据库引擎创建的两个表 - 一个是 Innodb,另一个是 MyISAM。

您可以使用以下命令更改数据库类型:ALTER TABLE t ENGINE = MYISAM;

@see http://dev.mysql.com/doc/refman/5.1/en/storage-engine-setting.html

创建表时要注意CHARSETCOLLATE参数。 在外键问题方面是这样的:

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'

在那次更正之后,我的问题就解决了。

如果有人在看似格式良好的 FK/PK 关系中遇到此错误并且您使用了可视化工具,请尝试删除有问题的 fk 列并在工具中重新添加它们。 我不断收到此错误,直到我重新绘制解决问题的连接。

对我来说,我试图将子表中的常规索引字段与父表中的主键匹配,默认情况下,一些 MySQL 前端 GUI(如 Sequel Pro)将主键设置为无符号,因此您必须确保子表字段也是无符号的(除非这些字段可能包含负整数,然后确保它们都是有符号的)。

MySQL 是出了名的古怪,尤其是在外键和触发器方面。 我现在正在微调一个这样的数据库,并遇到了这个问题。 它不是不言自明或直观的,所以它是这样的:

除了检查要在关系中引用的两列是否具有相同的数据类型外,还必须确保要引用的表中的列是索引。 如果您使用的是 MySQL Workbench,请选择“列”旁边的选项卡“索引”,并确保外键引用的列是索引。 如果没有,请创建一个,将其命名为有意义的名称,并为其指定类型“INDEX”。

一个好的做法是清理关系中涉及的表,以确保以前的尝试没有创建您不想要或不需要的索引。

我希望它有所帮助,一些 MySQL 错误令人抓狂。

第一个问题:我可以制作一个也是外键的主键吗?

是的。 事实上,对于 MySQL 工作台,我已经养成只使用主键作为外键的习惯。 确实减少了收到的随机错误,如问题中所述的 err:150 。

# 错误:错误 1005:无法创建表 'dbimmobili.condoni' (errno: 150)

这确实与索引有关,或者更具体地说,MySQL 工作台如何解释和使用它们。 如果您在同一个正向工程操作中对模型(例如外键、索引、列顺序)进行了大量更改,则真的会感到困惑,尤其是在另一端已经有数据库的情况下 例如,我认为自动创建的索引不会在删除外键后自动删除。

这是我为修复您收到的错误所做的工作。 请注意,这看起来很麻烦,但与我使用其他方法所花费的时间相比,事实并非如此。

1. 将所有外键设为查找表中的主键(1 对多中的 1)。

在我的例子中,这涉及将 id 作为 pk 更改为 tbl_users 中的用户名、tbl_companies 中的用户名 AND 公司以及 tbl_company_contacts 中的用户名 AND 公司 AND 联系人。 这是一款供多个用户输入多个公司联系人的应用程序,允许重叠和隐藏其他用户的联系人。

2. 删除所有图关系和所有不是主键的表索引。

这修复了大多数真正由错误的 MySQL 工作台引起的索引问题。

3. 如果您从头到尾都这样做,请删除服务器上的架构,这样 mysql 工作台就不会对现有索引感到困惑,也不会在模型中缺少索引(问题是由索引和外键关系引起的,而不是单独的索引) )。

这减少了数据库、服务器和 Mysql 工作台必须做出的大量决策。 这些关于如何对某些东西进行正向工程的决定既复杂又聪明,但并不完美。

4. 现在,我认为这又回到了原点(通常在没有分步过程的情况下设计得太快之后)。 我还有所有的桌子,但在这个阶段它们是干净的。 现在你只需:

首先,正向工程师只是为了确保表(没有关系)按预期工作。

沿着关系链向下通过主键,从最顶层的表开始(我是从 tbl_users 到 tbl_companies)。 每个关系之后,一直在向前发展工程,以确保它运行,然后保存模型并关闭,然后反向工程的模型,以确保需要 这允许您在问题出现时快速隔离问题,在我的情况下,旧的已删除外键使用的索引遗留下来(发生了 2-3 次)。

塔达,回到你需要去的地方。

这不是您的具体情况,但对于其他人来说值得注意的是,如果您尝试引用表中的某些字段而不是该表的整个主键,则可能会发生此错误。 显然这是不允许的。

当主键有 2 列时,它们构成一个复合主键,因此您必须确保在被引用的表中也有 2 列具有相同的数据类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM