跳到内容

多对多 - 简介

我们已经看到了如何在数据中使用一对多关系。

但是如何处理多对多关系呢?

让我们来探索一下。🚀

从一对多开始

让我们从熟悉且更简单的一对多选项开始。

我们有一个包含团队的表和一个包含英雄的表,对于每个一个团队,我们可以拥有多个英雄。

由于每个团队可能有多个英雄,我们将无法在 team 表中为所有英雄的 ID 设置列。

但是由于每个英雄只能属于一个团队,因此我们在英雄表中有一个单列指向特定的团队(指向 team 表中的特定行)。

team 表如下所示

idnameheadquarters
1PreventersSharp Tower
2Z-ForceSister Margaret's Bar

提示

请注意,它没有任何指向其他表的外键。

hero 表如下所示

idnamesecret_nameageteam_id
1DeadpondDive Wilsonnull2
2Spider-BoyPedro Parqueadornull1
3Rusty-ManTommy Sharp481

我们在 hero 表中有一列 team_id,它指向 team 表中特定团队的 ID。

这就是我们将每个 heroteam 连接的方式

table relationships

请注意,每个英雄只能有一个一个连接。 但是每个团队可以接收多个连接。 特别是,Preventers 团队有两个英雄。

介绍多对多

但是假设由于 Deadpond 是一个很棒的角色,他们将他招募到新的 Preventers 团队,但他仍然是 Z-Force 团队的一员。

因此,现在,我们需要能够让一个英雄与多个团队连接。 然后,每个团队仍然应该能够接收多个英雄。 因此,我们需要一个多对多关系。

一种效果不佳的简单方法是在 hero 表中添加更多列。 假设我们添加两个额外的列。 现在我们可以将单个 hero 总共连接到 3 个团队,但不能更多。 因此,我们并没有真正解决支持多个团队的问题,只是支持了非常有限的固定数量的团队。

我们可以做得更好!🤓

我们可以创建另一个表,该表表示 heroteam 表之间的链接。

此表包含的全部内容是两列,hero_idteam_id

这两列都是外键,指向 heroteam 表中特定行的 ID。

由于这将表示英雄-团队-链接,因此我们称该表为 heroteamlink

它看起来像这样

many-to-many table relationships

请注意,现在表 hero 不再有 team_id 列,它被此链接表替换。

并且 team 表,就像以前一样,也没有任何外键。

具体来说,新的链接表 heroteamlink 将是

hero_idteam_id
11
12
21
31

Info

链接表的其他名称包括

  • 关联表
  • 辅助表
  • 连接表
  • 中间表
  • 连接表
  • 通过表
  • 关系表
  • 连接表

我使用术语“链接表”是因为它很短,不与其他已使用的术语(例如“关系”)冲突,并且很容易记住如何编写它等等。

太棒了,我们有一个只有两列的链接表。但是请记住,SQL 数据库要求每行都有一个主键,该主键唯一标识该表中的行?

现在,此表中的主键是什么?

我们如何识别每个唯一的行?

我们是否应该添加另一列,使其成为此链接表的主键?不用!我们不必这样做。👌

这两列都是此表中每一行的主键(并且每行只有这两列)。✨

主键是一种在单个表唯一标识特定行的方法。但是它不必是单个列。

主键可以是表中的一组列,这些列在该表中组合起来是唯一的。

再次检查上面的表,看到每行的 hero_idteam_id 的组合都是唯一的吗?

我们不能有重复的主键,这意味着我们不能在 heroteam 之间有重复的链接,这正是我们想要的!

例如,数据库现在将阻止类似这样的错误,其中包含重复的行

hero_idteam_id
11
12
21
31
3 🚨1 🚨

让一个英雄两次成为同一个团队的成员是没有意义的,对吧?

现在,仅通过使用这两列作为此表的主键,SQL 将负责防止我们重复 heroteam 之间的链接。✅

回顾

带有回顾的简介! 这很奇怪……但无论如何。🤷

现在您了解了关于多对多关系的理论,以及如何在 SQL 中使用表来解决它们。🤓

现在让我们检查一下如何编写 SQL 和代码来使用它们。🚀