跳到内容

多对多 - 简介

我们了解了如何处理数据中的一对多关系。

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

让我们来探索一下。🚀

从一对多开始

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

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

由于每个团队可以有多个英雄,我们无法在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

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

引入多对多

但假设死侍是一个很棒的角色,他们把他招募到新的预防者团队,但他仍然是Z-Force团队的一员。

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

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

我们可以做得更好!🤓

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

这个表只包含两列:hero_idteam_id

这两列都是外键,指向hero表和team表中特定行的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和代码来处理它们。🚀