我使用的是 MySQL 版本 8.3.0。
我可以使用以下 SQL 语句在人员和团队表之间创建“多对多”关系:
create table persons (
id bigint not null,
last_name varchar(255) not null,
first_name varchar(255),
primary key (id)
);
create table teams (
id bigint not null,
team_name varchar(255) not null,
primary key (id)
);
create table person_team (
person_id bigint not null,
team_id bigint not null,
primary key (person_id, team_id),
constraint fk_person_team_person foreign key (person_id) references persons(id),
constraint fk_person_team_team foreign key (team_id) references teams(id)
);
因此该person_team
表有一个复合主键,并且它的每一列都是它所连接的表的外键。
person_team
如果我检索with 的DDL 语句show create table person_team;
,它会给出以下 SQL:
CREATE TABLE `person_team` (
`person_id` bigint NOT NULL,
`team_id` bigint NOT NULL,
PRIMARY KEY (`person_id`,`team_id`),
KEY `fk_person_team_team` (`team_id`),
CONSTRAINT `fk_person_team_person` FOREIGN KEY (`person_id`) REFERENCES `persons` (`id`),
CONSTRAINT `fk_person_team_team` FOREIGN KEY (`team_id`) REFERENCES `teams` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
因此它会自动向表KEY
中添加一条名为外键的指令(第 5 行)teams
。
为什么会有这种行为?这个额外的KEY
说明对我来说听起来不需要。为什么它显示的是 forfk_person_team_team
而不是 for 的密钥fk_person_team_person
?最初的陈述是否错误或不完整?自动生成的DDL是否正确?当我使用 转储数据库时mysqldump
,我获得了与自动生成的 DDL 相同的代码。修改这段代码来恢复数据库是否更安全?
有时会出现这种情况,答案可以在文档中找到:
(强调我的)。
person_team
您在:person_id
和team_id
;中有两个引用列前者被表的主键覆盖,而后者则没有,因为它不在PK中的第一个位置,所以为其创建一个额外的索引。原因是这样的:外键引用
fk_person_team_person
已经看到一个可以满足外键关系的索引。在您的情况下,它是主键,因为前导列是person_id
。至于另一个外键参考,
fk_person_team_team
,不存在能够满足外键关系的索引。我们用下面的代码来证明这一点
这将首先创建没有 FK 的 person_team 表。然后我会一次添加一个 FK
这是结果
请注意以下事项