MySQL - Error: 150 "Foreign key constraint is incorrectly formed")
MySQL - Error: 150 "Foreign key constraint is incorrectly formed")
遇到一个奇怪的问题,在浏览了数十个论坛帖子和我的本地 SQL 书籍后仍无法解决。
我有两张表,想给其中一张添加外键。外键和主键共享相同的数据类型和字符集,但我根本无法添加外键。
addon_account
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;
无法正常工作。一直抛出同一个问题。
我不完全是 MySQL 人,但是:
我认为问题在于您仅引用了主键的一部分:
您的 table 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不太熟悉。
您正在 addon_account_data(account_name)
上创建引用 addon_account(name)
的外键。你有一个复合主引用 table : addon_account(id, name)
.
这在 MySQL 中是不允许的,如 documentation 中所述:
MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan. In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order.
可能的解决方案:
在引用 table 中添加一个附加列:addon_account_data(account_id, account_name)
并为 addon_account
中的相应列创建一个复合主键
在 addon_account(name)
上创建索引(可能是最简单的解决方案)
更改所引用 table 的主键中列的顺序,例如:addon_account(name, id)
(您可能需要首先考虑这可能对术语产生的影响性能)
确保 2 个表具有相同的排序规则
像
整理='utf8_general_ci'
遇到一个奇怪的问题,在浏览了数十个论坛帖子和我的本地 SQL 书籍后仍无法解决。
我有两张表,想给其中一张添加外键。外键和主键共享相同的数据类型和字符集,但我根本无法添加外键。
addon_account
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;
无法正常工作。一直抛出同一个问题。
我不完全是 MySQL 人,但是:
我认为问题在于您仅引用了主键的一部分: 您的 table 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不太熟悉。
您正在 addon_account_data(account_name)
上创建引用 addon_account(name)
的外键。你有一个复合主引用 table : addon_account(id, name)
.
这在 MySQL 中是不允许的,如 documentation 中所述:
MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan. In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order.
可能的解决方案:
在引用 table 中添加一个附加列:
中的相应列创建一个复合主键addon_account_data(account_id, account_name)
并为addon_account
在
addon_account(name)
上创建索引(可能是最简单的解决方案)更改所引用 table 的主键中列的顺序,例如:
addon_account(name, id)
(您可能需要首先考虑这可能对术语产生的影响性能)
确保 2 个表具有相同的排序规则 像 整理='utf8_general_ci'