【问题标题】:Grounds for having a one to one relationship between tables表之间存在一对一关系的理由
【发布时间】:2013-12-02 22:51:51
【问题描述】:

如果我有两种不同类型的用户,父母和孩子。它们具有相同的字段,但是 Child 与考试具有一对多关系,而 Parent 则不存在这种关系。

最好将 Parent 和 Child 建模为单个表,还是组合在一起?

如果我有两种不同类型的用户,父母和孩子怎么办。除了一个孩子属于一所学校(一所学校有很多孩子)之外,它们是相同的

再一次,Parent 和 Child 最好建模为单个表,还是组合在一起?

【问题讨论】:

  • 我认为你应该有两张表:一张给父母,一张给孩子,它们之间有一个“一对多”的完整性约束。作为父母可以有一个或多个孩子;)
  • 如果记录中包含的数据相同,那么它们应该在同一个表中。因此,假设您有包含字段“年龄”、“身高”、“体重”和“类型”的人员记录,其中类型区分“父”或“子”(如果这甚至是必要的),它们是否在同一张表与否,但您通常会将它们放在同一张表中,以便更轻松地在数据库中查找人员。如果子记录需要包含与父记录无关的外键,那么当然可以将它们放在不同的表中。

标签: mysql sql database database-design database-schema


【解决方案1】:

他们有相同的字段,但是孩子与考试有一对多的关系

即使字段相同,不同的约束1也意味着您正在处理逻辑上独立的实体。在没有其他因素的情况下,应将单独的实体放入单独的物理表中。

但是,可能有相反的原因。例如,如果有一个键需要在父子组合中是唯一的,或者有另一个表需要引用它们等等......

如果是这种情况,那么从逻辑上讲,“父”和“子”都从“人”继承,包含公共约束(和字段)。这种“继承”可以通过将整个层次结构存储到单个表中(并将未使用的“部分”设置为 NULL)来表示,或者通过将所有三个“类”分离到它们自己的表中,并从“继承类”,例如2:

PERSON_ID 在所有父母和孩子中都是唯一的。除此之外,OTHER_TABLE 可以直接引用它,而不必单独引用 PARENT_ID 或 CHILD_ID。


1 在这种情况下是外键。

2 一个非常简化的模型,只是说明了上述观点,并没有尝试对您在问题中提到的所有内容进行建模

【讨论】:

    【解决方案2】:

    毫无疑问,父母和孩子都是人。永远不要将它们放在单独的表中。

    只有时间将他们分开:如果孩子成为父母怎么办?

    父母可以轻松地拥有孩子,您需要一个关系表。 此外,关系表是对学校成员进行建模的正确方法。

    这里有表格:

    person
    is_child_of (many to many, join table) --> relations between persons can be is_parent_of
    

    简单明了

    记住:作为一个孩子是人与人之间的关系。 如果需要,您将如何为孙子建模?还有一张桌子?还有曾孙?

    假设您对此感到满意,并且为许多“类型”关系制作了很多表,突然间您希望您必须添加一个字段(出生日期)或更改字段格式:您必须在所有不同的表中执行此操作。

    【讨论】:

    • 谢谢,让我玩个鬼鼓吹,充分理解你的推理。如果我将问题限制在三年内,从而否定你关于只有时间将它们分开的论点怎么办?
    • 甚至比。更多:约束往往不是,变化:臭名昭著的 2K 问题就是一个例子:那里的所有数据库都不打算在 2000 年之后出现。埃菲尔铁塔也只建立了很短的一段时间:)跨度>
    【解决方案3】:

    您在问题中描述了三个不同的实体——父母、孩子和考试。您已经展示了三者之间的关系有何不同。

    从您问题中的所有内容来看,我会说您有三个实体,您应该在数据库中设置它们。也就是说,Parent 和 Child 应该有单独的表。

    【讨论】:

      【解决方案4】:

      如果项目在您的系统中建模不同,我会说它们应该是不同的表。仅仅因为父母和孩子都具有相似的属性(姓名、年龄等),并不意味着他们将始终与数据库中的其他实体具有相同的关系。您可以让父母和孩子在同一个表中,列将孩子与父母相关联,但这只会在尝试表示这种关系时导致尴尬的自联接查询。如果一个孩子有两个父母,这本身就会变得非常奇怪。所以对我来说,你会有许多不同的表:

      parent
      child
      child_to_parent (many-to-many join table)
      school
      child_to_school (one school to many children)
      classes
      child_to_classes (many-to-many)
      classes_exams (one-to-many table relating exams to classes)
      child_to_classes_exams (many-to-many table relating children to exams for specific classes)
      * and maybe things like the following
      teacher
      teacher_to_classes (many-to-many)
      

      当然,在您的类设计中(如果您使用 OOP),您可以让子类和父类从一个公共“人”类扩展,该类将处理设置公共属性的逻辑。

      【讨论】:

      • “并不意味着它们将始终与数据库中的其他实体具有相同的关系”-> 当然不是。这就是为什么您应该在单独的表中对这些关系建模
      • @Peter 绝对应该在 IMO 单独的表中。
      • 如何用你的模型给孙子建模?
      • @Peter 这没有被指定为需要的东西。当不需要时,无需在此处引入树结构。在学校的孩子是否有祖父母作为监护人的情况下,也许“父母”表可能会更好地标记为“监护人”,这样它就不能确定某人是否是亲生父母。跨度>
      • 老实说:我以“未指定”为生,事情总是在变化。建模是为了应对未来的变化,而无法回答“whatif”问题通常是模型的味道。
      【解决方案5】:

      我会将孩子分成单独的表格,原因很简单,因为父母可能有很多孩子(如果不是现在,可能在将来)。

      除了当前的需要之外,考虑未来可能发生的事情也很重要,即使现在没有意义。您可能有两个家长用户想要管理一个孩子和那个孩子的考试。

      考虑最可能的未来功能需求,并牢记这些需求。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-25
        • 1970-01-01
        相关资源
        最近更新 更多