【问题标题】:Many to Many mapping without join table没有连接表的多对多映射
【发布时间】:2014-12-22 17:27:12
【问题描述】:

我有一个关于映射表的问题,我读过很多参考资料都说没有连接表很难进行多对多映射。

但是如果表 A 有一个来自表 B 的外键,反之亦然,例如 STUDENT 表有一个来自 CLASS 表的外键,它代表每个学生的班级“班级对学生一对多”,而 CLASS 表有来自 STUDENT 表的外键,表示属于“一对多班级的学生”的学生?

【问题讨论】:

    标签: sql database orm relational-database


    【解决方案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。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-04
      • 1970-01-01
      • 2022-08-24
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      相关资源
      最近更新 更多