没有连接表的多对多映射
Posted
技术标签:
【中文标题】没有连接表的多对多映射【英文标题】:Many to Many mapping without join table 【发布时间】:2014-12-22 17:27:12 【问题描述】:我有一个关于映射表的问题,我读过很多参考资料都说没有连接表很难进行多对多映射。
但是如果表 A 有一个来自表 B 的外键,反之亦然,例如 STUDENT 表有一个来自 CLASS 表的外键,它代表每个学生的班级“班级对学生一对多”,而 CLASS 表有来自 STUDENT 表的外键,表示属于“一对多班级的学生”的学生?
【问题讨论】:
【参考方案1】:当您的STUDENT
表有CLASS
表的外键时,这意味着每个学生行最多可以对应一个班级行。反过来,这意味着当一个学生上不止一门课时,您必须为同一个学生输入多行。
同样,当您的CLASS
表有一个指向STUDENT
表的外键时,您的模型假定一个课程最多可以由一个学生参加,或者由CLASS
表中的多行表示.
如果同一项目有多行,则您的数据非规范化。这通常是一件坏事。虽然在某些情况下您无法避免它而不会对性能造成太大影响,但这绝对不是其中之一。
这就是为什么您需要一张桌子“介于”学生和班级之间。
【讨论】:
【参考方案2】:如果您有一个正确规范化的数据库,那么您给出的示例将不起作用。只需考虑以下概念:
在您的学生表中,您应该有一个定义每个学生的主键。这意味着每个人只会有一行。您将有一个代表该类的列,但同样,如果您遵循正确的设计技术,该列应该只包含一个值。这意味着,您只能为每个学生安排一行,并且只能为他们分配一个班级。同样适用于类,你应该只有一行,即使你给它一个学生列,它也只能引用一个学生。
当然,你可以有一个糟糕的设计,允许多排学生,但它会为无数异常打开,并且保持前进会很糟糕。我强烈建议不要这样做。
我建议您创建一个交叉表,该表使用课程和学生参考的复合键。您的设计可能如下所示:
student:
| student_id | name | phone |
course:
| course_id | description | location |
enrollment:
| course_id | student_id |
编辑
如果您按照上述说明操作,您在 cmets 中提到的内容将不起作用。考虑这个不允许学生超过一行的学生表:
| student_name | class |
+--------------+---------+
| John | Science |
| Adam | Math |
| Jane | Science |
现在,没有什么能阻止我创建这样的类表:
| class | student_name |
+---------+--------------+
| Science | Joe |
| Math | Jane |
是的,所有信息都在那里。我知道 Adam 学数学,John 学科学,Joe 学科学,而 Jane 学数学和科学。
但是现在,如果亚当也想学科学怎么办?他不能,因为Science
已经有一行,Adam
已经有一行。如果更改其中任何一个,就会丢失一条信息。
【讨论】:
我可以通过在班级表的多行上使用相同的 student_FK 来为一个学生开设多个班级,并且我可以通过在学生表的多行上使用相同的 class_FK 来为一个班级开设多个学生。 虽然它可能在一定程度上起作用,但您会很快发现缺点。请查看我的编辑,@user3305603。以上是关于没有连接表的多对多映射的主要内容,如果未能解决你的问题,请参考以下文章