当表A中的每个记录在表B中可能有许多链接记录时,数据库中出现一对多关系,但表B中的每个记录在表A中可能只有一个相应的记录。一对多关系在数据库是最常见的关系数据库设计,是良好设计的核心。
考虑一下教师与他们教授的课程之间的关系。教师可以教授多门课程,但课程与老师的关系不同。
因此,对于Teachers表中的每条记录,Courses表中可能有许多记录。这是一对多的关系:一个教师到多个课程。
为什么建立一对多关系很重要
要表示一对多关系,您至少需要两个表。让我们看看为什么。
也许我们创建了一个表格,我们想要记录所教授的名称和课程。我们可能会这样设计:
Teacher_ID | 老师的名字 | 课程 |
---|---|---|
Teacher_001 | 卡门 | 生物学 |
Teacher_002 | 维罗尼卡 | 数学 |
Teacher_003 | 乔治 | 英语 |
如果Carmen教两门或更多课程怎么办?这种设计有两种选择。我们可以将它添加到Carmen的现有记录中,如下所示:
Teacher_ID | 老师_名称 | 课程 |
---|---|---|
Teacher_001 | 卡门 | 生物学,数学 |
Teacher_002 | 维罗尼卡 | 数学 |
Teacher_003 | 乔治 | 英语 |
但是,上述设计不灵活,以后在尝试插入,编辑或删除数据时可能会出现问题。
这使得搜索数据变得困难。这种设计违反了数据库规范化的第一个原则,即第一范式(1NF),它规定每个表格单元格应包含单个独立的数据。
另一种设计方案可能是简单地为Carmen添加第二条记录:
老师_ID | 老师_名称 | 课程 |
---|---|---|
Teacher_001 | 卡门 | 生物学 |
Teacher_001 | 卡门 | 数学 |
Teacher_002 | 维罗尼卡 | 数学 |
Teacher_003 | 乔治 | 英语 |
这坚持1NF但仍然是糟糕的数据库设计,因为它引入了冗余并且可能不必要地膨胀非常大的数据库。更重要的是,数据可能会变得不一致。例如,如果Carmen的名字改变了怎么办?使用数据的人可能会在一条记录中更新其名称,并且无法在第二条记录中更新它。此设计违反了第二范式(2NF),它遵循1NF,并且还必须通过将数据子集分成多个表并在它们之间创建关系来避免多个记录的冗余。
如何设计具有一对多关系的数据库
要在Teachers and Courses表中实现一对多关系,我们将表分成两部分并使用外键链接它们。
在这里,我们删除了Teachers表中的Course列:
老师_ID | 老师_名称 |
---|---|
Teacher_001 | 卡门 |
Teacher_002 | 维罗尼卡 |
Teacher_003 | 乔治 |
这是课程表。请注意,其外键Teacher_ID将课程链接到Teachers表中的教师:
COURSE_ID | 课程名 | Teacher_ID |
---|---|---|
Course_001 | 生物学 | Teacher_001 |
Course_002 | 数学 | Teacher_001 |
Course_003 | 英语 | Teacher_003 |
我们使用外键在教师和课程表之间建立了关系。
这告诉我们,生物学和数学都是由卡门教授的,而乔治教授英语。
我们可以看到这种设计如何避免任何可能的冗余,允许个别教师教授多个课程,并实现一对多的关系。
数据库还可以实现一对一的关系和多对多的关系。