【问题标题】:MySQL - Error: 150 "Foreign key constraint is incorrectly formed")MySQL - 错误:150“外键约束格式不正确”)
【发布时间】:2020-02-19 00:07:45
【问题描述】:

在浏览了几十个论坛帖子和我的本地 SQL 书籍后,遇到了一个我无法解决的奇怪问题。

我有两张表,想为其中一张表添加外键。外键和主键共享相同的数据类型和字符集,但我根本无法添加外键。

插件帐户

name type comments
id int(11) Primary Key
name varchar(60) Primary Key
label varchar(255)
shared int(11)

addon_account_data

name type comments
id int(11) Primary Key
account_name varchar(60) Primary Key
money double
owner varchar()

我运行的查询:

ALTER TABLE `addon_account_data` ADD FOREIGN KEY (`account_name`) REFERENCES `addon_account`(`name`) ON DELETE RESTRICT ON UPDATE RESTRICT;

无法让它工作。一直在抛出同样的问题。

【问题讨论】:

  • 您能否运行show create table addon_accountshow create table addon_account_data 并将结果添加到您的问题中?
  • InnoDB 允许外键引用任何索引列或列组。但是,在引用的表中,必须有一个索引,其中引用的列是相同顺序的第一列' - dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
  • 这是一个常见问题解答。在考虑发布之前,请始终使用谷歌搜索您的错误消息或您的问题/问题/目标的许多清晰、简洁和精确的措辞,有或没有您的特定字符串/名称和站点:stackoverflow.com 和标签,并阅读许多答案。如果您发布问题,请使用一个短语作为标题。请参阅How to Ask 和投票箭头鼠标悬停文本。 PS FK 约束表示表中的子行在其他地方显示为 PK/UNIQUE。所以你的声明没有意义。你认为你是如何限制数据库的?

标签: mysql foreign-keys primary-key mysql-error-1005 mysql-error-150


【解决方案1】:

我不完全是 MySQL 人,但是:

我认为问题在于您仅引用了主键的一部分: 您的表 addon_account 有一个复合键 PK(id, name)。

因此,为了让您的关系发挥作用,您还需要将“account_id”添加为外键的一部分:

ALTER TABLE addon_account_data ADD FOREIGN KEY (account_id, account_name) REFERENCES addon_account(id, name)

This thread 处理类似的事情。

我希望这会有所帮助。

已编辑

我已经在我的本地机器上安装了一个 MySQL 服务器实例...(MySQL 8)。

我已经运行了下面的脚本,并且它有效(警告整数显示是一个已弃用的功能,所以我建议省略它):

CREATE TABLE addon_account(
id INT(11) NOT NULL,
`name` VARCHAR(60) NOT NULL,
label VARCHAR(255),
shared INT(11),
CONSTRAINT pk_addon_account PRIMARY KEY(id, `name`));


CREATE TABLE addon_account_data (
id INT(11) NOT NULL,
account_name VARCHAR(60) NOT NULL,
account_id INT(11),
money DOUBLE,
`owner` VARCHAR(255),
CONSTRAINT pk_addon_account_data PRIMARY KEY(id, account_name),
CONSTRAINT fk_addon_account_account_data FOREIGN KEY(account_id, account_name)
    REFERENCES addon_account(id, `name`));

你能试试看这是否适合你?

我对 MySQL 不是很熟悉。

【讨论】:

  • 似乎不起作用,但是我确定了问题所在。如果我删除 PK id,它可以工作。如果有人对如何在复合 PK 上添加 FK 有答案,那就太好了!
  • 这真的很奇怪。我这里没有 MySQL 数据库,我会在晚上创建表(巴西),然后用我找到的任何内容编辑我的答案。
  • 我已经处理 MySQL 数据库几年了,这让我感到沮丧和困惑。虽然我不会在这里停止测试 rn。我需要这个才能工作..还有大约 50 个表要通过,每个带有复合 pk 的表都有这个问题。
  • 如果我能给你一个建议......我已经制作了这个脚本,反映了你在问题中公开的相同模式。为了避免将来出现一些麻烦,如果不同的帐户 id 可以使用相同的帐户名,我也会制作包含“account_id”属性的“addon_account_data”PRIMARY KEY。
【解决方案2】:

您正在 addon_account_data(account_name) 上创建一个引用 addon_account(name) 的外键。您有一个复合主引用表:addon_account(id, name)

这在 MySQL 中是不允许的,如 documentation 中所述:

MySQL 需要外键和引用键的索引,以便外键检查可以快速且不需要表扫描。在引用表中,必须有一个索引,其中外键列按相同顺序列为第一列。

可能的解决方案:

  • 在引用表中添加一个附加列:addon_account_data(account_id, account_name),并为addon_account中的相应列创建一个复合主键

  • addon_account(name) 上创建索引(可能是最简单的解决方案)

  • 更改引用表的主键中列的顺序,例如:addon_account(name, id)(您可能需要首先考虑这可能对性能产生的影响)

【讨论】:

    【解决方案3】:

    确保 2 个表具有相同的排序规则 喜欢 COLLATE='utf8_general_ci'

    【讨论】:

      猜你喜欢
      • 2021-03-01
      • 2017-01-05
      • 2018-09-04
      • 2018-12-02
      • 1970-01-01
      • 2021-11-07
      • 1970-01-01
      • 1970-01-01
      • 2018-06-19
      相关资源
      最近更新 更多