跳到内容

多对多 - 介绍

我们了解了如何在数据中使用一对多关系。

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

让我们来探索它们。🚀

从一对多开始

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

我们有一个团队表和一个英雄表,对于每一个个团队,我们可以有个英雄。

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

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

team表如下所示

idname总部
1阻止者锐利之塔
2Z-部队玛格丽特修女酒吧

提示

请注意,它不包含任何指向其他表的外键。

hero表如下所示

idnamesecret_nameageteam_id
1死侍戴夫·威尔逊2
2蜘蛛男孩佩德罗·帕尔克多1
3锈人汤米·夏普481

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

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

table relationships

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

引入多对多

但假设Deadpond是一个很棒的角色,他们把他招募到了新的Preventers团队,但他仍然是Z-Force团队的一部分。

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

一个不太有效的简单方法是向hero表中添加更多列。想象一下我们添加了两列。现在我们可以将一个hero总共连接到3个团队,但不能更多。所以我们并没有真正解决支持多个团队的问题,而只是一个非常有限的固定数量的团队。

我们可以做得更好!🤓

我们可以创建另一个表,用于表示hero表和team表之间的链接。

此表仅包含两列:hero_idteam_id

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

由于这表示英雄-团队-链接,我们将其命名为heroteamlink表。

它看起来像这样

many-to-many table relationships

请注意,现在hero不再有team_id,它被这个链接表取代了。

team表,和以前一样,也没有任何外键。

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

hero_idteam_id
11
12
21
31

信息

链接表的其他名称包括

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

我使用“链接表”这个术语,因为它很短,不会与其他已使用的术语(例如“关系”)冲突,易于记忆如何书写,等等。

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

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

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

我们是否应该添加另一列作为这个链接表的主键?不!我们不必这样做。👌

这两列都是该表中每行的主键(而且每行只有这两列)。✨

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

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

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

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

例如,数据库现在将阻止像这样带有重复行的错误

hero_idteam_id
11
12
21
31
3 🚨1 🚨

英雄两次属于同一个团队是没有意义的,对吗?

现在,只需将这两列用作该表的主键,SQL就会阻止我们重复heroteam之间的链接。✅

回顾

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

现在你已经掌握了多对多关系的理论,以及如何用SQL中的表来解决它们。🤓

现在让我们看看如何编写SQL和代码来处理它们。🚀