没有连接表的多对多映射

时间:2014-12-22 17:27:12

标签: sql database orm relational-database

我有一个关于映射表的问题,我已经阅读了很多参考文献,说很难在没有连接表的情况下进行多对多映射。

但是如果表A具有来自表B的外键并且反之亦然,例如,STUDENT表具有来自CLASS表的外键,其表示每个学生的班级"班级给学生一对多" ,CLASS表中有一个来自STUDENT表的外键,表示属于学生一到多的学生"?

2 个答案:

答案 0 :(得分:2)

当您的STUDENT表具有CLASS表的外键时,这意味着每个学生行最多可以对应一个类行。反过来,这意味着当学生需要多个课程时,您必须为同一个学生输入多行。

同样,当您的CLASS表具有STUDENT表的外键时,您的模型假定一个类最多只能由一个学生学习,或者由多个行表示。 CLASS表。

当同一项目有多行时,您的数据将非规范化。这通常是件坏事。虽然有一些情况下你不能在不损害性能的情况下避免它,但这绝对不是其中之一。

这就是为什么你想要一张桌子"介于两者之间"你的学生和你的班级。

答案 1 :(得分:1)

如果您拥有正确规范化的数据库,那么您提供的示例将无效。只需考虑以下概念:

在您的学生表中,您应该拥有定义每个学生的主键。这意味着每个只有一行。您将拥有一个代表该类的列,但是,如果您遵循正确的设计技术,该列应该只包含一个值。这意味着,每个学生只能拥有一行,并且只能为他们分配一个班级。同样适用于课程,你应该只有一行,即使你给它一个学生专栏,它也只能引用一个学生。

当然,你可能有一个糟糕的设计,允许多排学生,但它会打开无数的异常,并保持前进将是可怕的。我强烈建议反对。

我建议您创建一个交叉表,该表使用课程和学生参考的复合键。你的设计看起来像这样:

student:
| student_id | name | phone |

course:
| course_id | description | location |

enrollment:
| course_id | student_id |

修改

如果您按照上述说明操作,那么您在评论中提到的内容将无效。考虑这个学生表不允许学生多行:

| student_name | class   |
+--------------+---------+
|    John      | Science |
|    Adam      | Math    |
|    Jane      | Science |

现在,没有什么能阻止我创建这样的类表:

| class   | student_name |
+---------+--------------+
| Science |    Joe       |
| Math    |    Jane      |

是的,所有信息都在那里。我知道亚当在数学,约翰在科学,乔在科学,简在数学和科学。

但是现在,如果亚当想要接受科学,会发生什么?他不能,因为Science已有一行而Adam有一行。如果你改变任何一个,你就会丢失一条信息。