Data modelling: parent and child 'dual' relationship
I am trying to create a proper parent/child relationship within my data model. I have a typical one to many relationship between the parent and children.
I am wondering if I have parents that know about their children, is it
- ever acceptable, and
- a good idea
for each child to specifically know about its parent?. (a child can only have one parent in my case)
parent
-------------
PARENT_ID
OTHER_COL
...
child
-------------
CHILD_ID
PARENT_ID // <-开发者_开发知识库- Should this column be here?
OTHER_COL
...
parent_has_children
--------------------
PARENT_ID
CHILD_ID
The advantage I see for having the parent column in the child, is for easily retrieving the parent from a child. But, is this just lazy design?
Thanks in advance.
TL;DR
Re the question:
child
PARENT_ID // <-- Should this column be here?
Yes, and if a foreign key constraint is added from child.PARENT_ID
referencing the parent column parent.PARENT_ID
, the integrity of the parent-child relationship will be enforced.
Should table
parent_has_children
exist?
No, a link or union table like this is used to model a many-many
relationship. A many-many relationship between tables P
and C
would imply that the same C
row can simultaneously associate many P
rows, and vice-versa. That is clearly not a parent-child relationship.
Modelling the 1-to-many relationship
If the relationship is 1 parent to many children (i.e. the same child can only belong to exactly one parent), then the standard modelling approach is to reference the Parent table from the Child table, via (one of) the Parent's key columns, usually the Parent's Primary Key (PK). At the same time, it is also a good idea to Foreign Key (FK) constraint on the reference column (child.PARENT_ID
) to encourage the RDMBS to enforce referential integrity across the relationship:
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)
The OP's additional many:many table parent_has_children
is redundant, as it will have exactly one row per child
, and it will soon become a burden to keep this table in sync
with rows added / removed from the other tables (as failure to keep this synchronized will result in confusion / contradiction in the integrity of the relationship).
Re : How do parents know about their children?
Child records for a given parent can be found using a simple query on the child table filtered on the parent foreign key column:
SELECT ...
FROM child
WHERE PARENT_ID = myParentId;
As this is usually a common query, it is always a good idea to ensure that the foreign key child.PARENT_ID
is indexed - some RDBMS versions do this for all foreign keys by default.
CREATE INDEX IXFoo on child(PARENT_ID);
If you have an entity model (e.g. for an ORM) in an application representing these tables, the parent entity will generally have a collection containing its child
instances, and on the child entity, the scalar foreign key child.PARENT_ID
'column' is either dropped entirely, or replaced with a reference to an instance of the parent:
class Parent
{
ParentId,
Child[] Children,
// ...
}
class Child
{
ChildId,
Parent Parent, // Optional, allows bidirectional navigation
// ...
}
If the relationship is truly one-to-many and not many-to-many then you would leave PARENT_ID
on the CHILD
table as the foreign key and drop the PARENT_HAS_CHILDREN
table altogether.
I would tend towards scrapping the parent_has_children table and instead just have a PARENT_ID on a child - this is the more conventional way of representing this data.
精彩评论