数据建模:父母和孩子的“双重”关系

Ste*_*ins 4 database database-design data-modeling relational-database

我正在尝试在我的数据模型中创建正确的父/子关系。我的父母和孩子之间有典型的一对多关系。

我想知道我是否有父母了解他们的孩子,是吗?

  1. 永远可以接受,并且
  2. 一个好主意

让每个孩子具体了解其父母?(在我的情况下,一个孩子只能有一个父母)

parent      
-------------
PARENT_ID
OTHER_COL
...

child
-------------
CHILD_ID
PARENT_ID    // <-- Should this column be here?
OTHER_COL
...

parent_has_children
--------------------
PARENT_ID
CHILD_ID
Run Code Online (Sandbox Code Playgroud)

我认为在子项中包含父列的优点是可以轻松地从子项中检索父项。但是,这只是懒惰的设计吗?

提前致谢。

Stu*_*tLC 6

长话短说

回复问题:

child
PARENT_ID    // <-- Should this column be here?
Run Code Online (Sandbox Code Playgroud)

是的child.PARENT_ID,如果通过引用父列添加外键约束parent.PARENT_ID,则将强制执行父子关系的完整性。

表应该parent_has_children存在吗?

,像这样的链接或联合表用于对many-many关系进行建模。P表和之间的多对多关系C意味着同一C行可以同时关联许多P行,反之亦然。这显然不是亲子关系。

建模一对多关系

如果关系是 1 个父级与多个子级(即同一个子级只能属于一个父级),则标准建模方法是通过父级的(其中一个)键列从子级表引用父级表,通常父级的主键 (PK)。同时,对引用列 ( ) 进行外键 (FK) 约束也是一个好主意,child.PARENT_ID以鼓励 RDMBS在整个关系中强制执行引用完整性:

parent      
-------------
PARENT_ID PRIMARY KEY, // PK for the parent table
OTHER_COL
...

child
-------------
CHILD_ID PRIMARY KEY,  // PK for the Child Table
PARENT_ID              // <-- Should this column be here? = Yes
CONSTRAINT FK_ChildParent FOREIGN KEY(PARENT_ID) REFERENCES parent(PARENT_ID)
Run Code Online (Sandbox Code Playgroud)

OP的额外的多:多表parent_has_children是多余的,因为它每个表只有一行,并且很快就会成为保持该表与其他表添加/删除的行的child负担(因为未能保持同步将导致混乱in sync/ 关系完整性中的矛盾)。

回复: 父母如何了解自己的孩子?

可以使用对根据父外键列过滤的子表的简单查询来找到给定父级的子记录:

SELECT ... 
FROM child 
WHERE PARENT_ID = myParentId;
Run Code Online (Sandbox Code Playgroud)

由于这通常是一个常见的查询,因此确保外键child.PARENT_ID被索引总是一个好主意 - 某些 RDBMS 版本默认对所有外键执行此操作。

CREATE INDEX IXFoo on child(PARENT_ID);
Run Code Online (Sandbox Code Playgroud)

如果您在代表这些表的应用程序中有一个实体模型(例如,ORM),则父实体通常会有一个包含其child实例的集合,并且在子实体上,标量外键child.PARENT_ID“列”要么完全删除,要么替换为对父实例的引用:

class Parent
{
    ParentId,
    Child[] Children,
    // ...
}

class Child
{
    ChildId,
    Parent Parent, // Optional, allows bidirectional navigation
    // ...
}
Run Code Online (Sandbox Code Playgroud)