简介

本文通过图文方式介绍了关系型数据库中的多对多关系。


读者水平要求

了解关系型数据库基本概念。


从例子说起

在学校里,有老师与学生的关系。学校里有张老师、赵老师、阮老师,还有学生小李、小王、小沈。

先从老师这边看老师与学生的关系:

张老师有3个学生小李、小王、小沈,所以关系是:张老师小李、小王、小沈)。

张老师的学生同时也是赵老师、阮老师的学生,所以,也有如下关系:

赵老师小李、小王、小沈

阮老师小李、小王、小沈


再从学生这边看学生与老师的关系:

小李同学有3个老师,他们是张老师、赵老师、阮老师,所以关系是:小李张老师、赵老师、阮老师)。

小李同学的老师同样也是小王同学、小沈同学的老师,所以有如下关系:

小王张老师、赵老师、阮老师

小沈张老师、赵老师、阮老师


关系如下图所示:

图1

关于多对多关系的一点理解_多对多


分析

我们分析一下,用代号标识他们,老师用T(T1张老师、T2赵老师、T3阮老师),学生用S(S1小李、S2小王、S3小沈),就有:

T1(S1, S2, S3)

T2(S1, S2, S3)

T3(S1, S2, S3)

S1(T1, T2, T3)

S2(T1, T2, T3)

S3(T1, T2, T3)

两两关系有:

T1S1,T1S2,T1S3,

T2S1,T2S2,T2S3,

T3S1,T3S2,T3S3,

S1T1,S1T2,S1T3,

S2T1,S2T2,S2T3,

S3T1,S3T2,S3T3。

分析得知,这是典型的双向多对多关联关系(Bidirectional many-to-many relationship)。


关系型数据库实现双向多对多关联关系

用关系型数据库映射后,数据库中产生三张表:T表、S表、R表(关系表)。

先看T表和S表(此处只用来演示关系,所以忽略表上所有不必要字段):

图2

关于多对多关系的一点理解_关系型数据库_02

这两张表很简单,分别有一个ID和一个Name。T表中T_ID是主键(PK),数值由数据库自动生成,全表唯一。TEACHER_NAME记录老师的姓名。同样,S表字段作用与T表的相同。

下面我们来看一下T表和S表的数据:

图3

关于多对多关系的一点理解_多对多_03

(此处不再赘述关系型数据库基础知识,主键、外键、关系约束等相关知识请自行查阅相关资料)

之前说过TS的关系是双向多对多关联关系,那么我们这里需要一张中间表即R表来存储T-S之间的关系信息。其实,T-S关系你可以理解为一条连接线,为了用数据描述这条连接线,你要先找出T、S两者中数据间的,不重复的关联关系(就是去数一下图1中老师、学生之间一共有多少条连接线)。

图1可知,3个老师、3个学生,他们之间一共有9条关联线。我们需要在R表中创建9条记录来描述这9个T-S间的关联关系:

图4

关于多对多关系的一点理解_关系型数据库_04

图4可以看出,T表中没有数据冗余,S表中也没有数据冗余。虽然R表中有数据冗余,但因为R表只保留了描述T-S关联关系所必须的键值,没有任何自然数据,例如,TEACHER_NAME或STUDENT_NAME,所以即便有冗余键值也在可以接受的范围之内。(在设计数据结构时,并非一定要遵循最高范式,在合适的位置放置一些冗余数据某些时候可以起到简化程序、提高数据访问效率的效果。作为设计者,你要根据业务目标、现实情况等客观条件来平衡“理想”与“现实”,这就是trade-off,生活中处处充满了trade-off)


总结

图4中R表每一条记录描述了T-S所有关系中的一种关联关系。通俗的说,你把两件事物按照一定的关系连接到一起时,这两件事物就算是扯上关系了。看着数据表我们可以尝试解读:

第1条关联关系(R_ID=1的那行记录)——张老师(T_ID=1)与学生小李(S_ID=1)的关系;

第2条关联关系(R_ID=2的那行记录)——张老师(T_ID=1)与学生小王(S_ID=2)的关系;

第3条关联关系(R_ID=3的那行记录)——张老师(T_ID=1)与学生小沈(S_ID=3)的关系;

第4条关联关系(R_ID=4的那行记录)——赵老师(T_ID=2)与学生小李(S_ID=1)的关系;

...(不啰嗦了,简化一下)...

R_ID5 (T_ID2, S_ID2)

R_ID6 (T_ID2, S_ID3)

R_ID7 (T_ID3, S_ID1)

R_ID8 (T_ID3, S_ID2)

R_ID9 (T_ID3, S_ID3)

至此,9个老师与学生的关系已经全部建立好了。

这就是利用关系型数据库为现实世界中事物的双向多对多关系进行建模的整个过程。