5

在表之间的识别和非识别关系的上下文中,MySQL 的文档将很多表称为父表和子表。

如何确定哪个表是父表,哪个表是子表?

4

3 回答 3

10

子表(AKA弱实体)是主键属性依赖于另一个表的表,因此子表由它所依赖的表(父表)中的行标识部分标识。如果没有父表中的相应行,子表中的行就不能存在。

为了说明,让我们举一个我们都熟悉的简单且完全相关的例子:家庭背景下的父母和孩子。我们可以用这样的表来模拟这种关系:

父子识别关系

在上面的模型中,Parents表中的每一行都由一个唯一标识SSN。是每个父级的SSN固有且唯一的属性,因此它是独立的或“强”实体,因为它不依赖另一个表来定义其身份。

但是,子项需要父项才能存在(Parent_SSN 必须SSN引用表中的现有Parents项)。

请注意表中的复合主键 ( Parent_SSN, Name) Children。这意味着通过 和 的组合唯一标识子项。您不能仅根据该字段查询单个孩子,因为多个父母可能有同名的孩子。同样,您不能仅根据字段查询单个子项,因为一个父项可能有多个子项。考虑到这一点,孩子被他们的父母部分识别,从而识别关系。Parent_SSN NameNameParent_SSN

但是,SSN 也不能唯一标识儿童吗?为什么是的,当然。让我们继续调整我们的模型以包括:

父子非识别关系

在这个版本的模型中,请注意我们已经SSNChildren. 儿童的独特身份现在由他们自己内在和独特的定义SSN。他们的身份不再依赖Parents桌子。尽管该Parent_SSN字段仍然引用表SSN的,但它与孩子的唯一身份无关,因此父母与其孩子有非识别关系,现在两个表都可以被认为是“强”独立实体。Parents

顺便说一句,这个版本的模型比第一个版本有一些优势:

  • 一个父级现在可能有两个或多个同名的子级,而先前模型中的实体完整性约束不允许这样做。
  • 您可以允许该Parent_SSN字段包含NULL以说明您拥有有关孩子的数据但不知道他/她的父母是谁的事件。

在上述两种模型中,Parents表都被认为是表的父Children表。但是,在第二个模型中的非标识关系中,Parents它只是外键上下文中的父表,Parent_SSN因为在表中Parent_SSN 引用/依赖,但在定义子项的实际身份时没有任何作用。SSNParents

为了说明为什么在决定哪些表是父/子表时上下文很重要,请考虑以下涉及循环依赖的示例:

员工部门关系

在此示例中,员工和部门由他们自己的属性唯一标识,并且不会从其他表中派生其身份的任何部分。

在这里,我们有两个非标识关系:一个员工为一个部门工作(DeptNoEmployee表中),一个部门由一个员工管理(ManagerSSNDepartment表中)。哪个是父表?...儿童桌?

这取决于上下文——你在说哪个外键关系?Department 表将被视为表上下文中的父表,DeptNo因为EmployeeDeptNo引用/依赖Department表。

但是,Employee 表将被视为表上下文中的父表,ManagerSSN因为DepartmentManagerSSN引用/依赖Employee表。

于 2012-06-19T22:26:23.030 回答
0

没有严格的规则可以确定表在关系中的角色。事实上,这就是关系模型的美妙之处和创新之处:没有层次结构。

通常,如果从某个表到另一个表存在硬依赖关系,则子角色或父角色由表的语义确定。示例:在 a order,order_details关系中,很明显那order是父母和order_details孩子。

在其他情况下,不清楚关系在关系中扮演什么角色。例子:orderscustomers关系。如果您执行查询以获取orders属于某个特定的所有内容,customer则父级可能是customers并且orders是子级。但是您也可以进行查询以获取customers特定 的所有装运信息(以相关方式存储)order,在这种情况下,您可能会争辩说在此查询中它order是父节点,而子节点是子节点。customers

正如我之前所说,当关系模型在 70 年代后期被发明时,它相对于一种主流范式(分层数据模型)的主要优势之一是能够查找相关数据而不管它们的依赖关系。

于 2012-06-19T20:31:33.630 回答
0

这里提出了一个很好的定义:

标识关系是子表中的行的存在依赖于父表中的行。(...) 形式上,“正确”的做法是使外键[即父主键]成为子主键的一部分。

于 2012-06-19T22:01:00.033 回答