[英]Proper way to model M:N relationship in SQL where parent may be one of many types
I have a situation where a particular child object may have multiple parents of different types. 我遇到一个特定的子对象可能具有多个不同类型的父对象的情况。 For example, a
foo
object may be a child of one ore more of a
, b
, or c
objects. 例如,
foo
对象可以是a
, b
或c
对象中a
或多个的子对象。 More over, I also have a bar
object which may also be a child of one or more a
, b
, or c
objects. 而且,我还有一个
bar
对象,它也可以是a
, b
或c
对象的一个或多个。 What's the proper way to model this in SQL? 在SQL中对此建模的正确方法是什么?
A) Single table for all relationships: A)所有关系的单个表:
relationship_tbl
parent_id parent_type child_id child_type
--------- ----------- -------- ----------
1 a 5 foo
2 a 6 foo
3 c 7 bar
4 b 7 bar
B) Unique table for each parent type: B)每个父类型的唯一表:
a_child_tbl
parent_id child_id child_type
--------- -------- ----------
1 5 foo
2 6 foo
b_child_tbl
parent_id child_id child_type
--------- -------- ----------
4 7 bar
c_child_tbl
parent_id child_id child_type
--------- -------- ----------
3 7 bar
C) Unique table for each child type: C)每个孩子类型的唯一表:
foo_parent_tbl
child_id parent_id parent_type
--------- ----------- -----------
5 1 a
6 2 a
bar_parent_tbl
child_id parent_id parent_type
--------- ----------- -----------
7 3 c
7 4 b
D) Unique table for each combination D)每个组合的唯一表
a_foo_tbl
parent_id child_id
--------- --------
1 5
2 6
b_bar_tbl
parent_id child_id
--------- --------
4 7
c_bar_tbl
parent_id child_id
--------- --------
3 7
E) Some other strategy that I haven't explored E)我没有探索过的其他策略
To me, it seems like A would be the easiest to query and answer questions like Find all the parents of child 7
or Find all the children of parent 4
, but I've read some advice that basically says never create generic tables for parent/child relationships. 对我来说,似乎A是最简单的查询和回答问题,例如“
Find all the parents of child 7
或“ Find all the children of parent 4
,但我读过一些建议,基本上说从不为父母/创建通用表儿童关系。
Could somebody shed some light on the best way to do this and why? 有人可以阐明这样做的最佳方法吗?为什么? It's safe to assume that the table will never have more than a few million rows in it.
可以肯定地说,表中的行永远不会超过几百万行。
I'd recommend a variation of your solution C. You need to have a separate M:N table for each M:N relationship, per Fourth Normal Form . 我建议您使用解决方案C的一种变体。对于每个M:N关系,您都需要有一个单独的M:N表(根据“ 第四范式”) 。
But also create a supertable to unify all the a, b, c parent types, so that the M:N tables can reference a single table, in which each parent_id is strictly assigned its respective type. 而且还要创建一个上表,以统一所有a,b,c父类型,以便M:N表可以引用一个表,其中每个parent_id都严格分配了各自的类型。
parent_tbl
parent_id parent_type
--------- -----------
1 a
2 a
3 c
4 b
a_parent_tbl
parent_id parent_type
--------- -----------
1 a
1 a
b_parent_tbl
parent_id parent_type
--------- -----------
4 b
c_parent_tbl
parent_id parent_type
--------- -----------
3 c
In each sub-parent table, the parent_type
is restricted to a single value. 在每个子父表中,
parent_type
被限制为单个值。 The parent_table
has a unique constraint on (parent_id, parent_type), and the foreign key in each sub-parent tables references the columns in that unique constraint. parent_table
对(parent_id,parent_type)具有唯一约束,并且每个子父表中的外键引用该唯一约束中的列。 Therefore no parent_id can be referenced by more than one sub-type. 因此,任何一个以上的子类型都不能引用parent_id。
Then your child M:N tables only need to reference parent_table
by ID. 然后,您的子M:N表仅需
parent_table
ID引用parent_table
。 You don't necessarily need a parent_type column in these tables, but you do if you need to create a UNIQUE constraint over (child_id, parent_type) so that each child can have only one parent of a given type. 这些表中不一定需要有parent_type列,但是如果需要在(child_id,parent_type)上创建UNIQUE约束,则每个子对象只能具有一个给定类型的父对象,则需要这样做。
foo_parent_tbl
child_id parent_id
-------- ---------
5 1
6 2
bar_parent_tbl
child_id parent_id
-------- ---------
7 3
7 4
You may also like to read: 您可能还喜欢阅读:
As long as types a,b,c,d are always parents, and types foo and bar can only be children (ie 'foo' could/will never be a parent of 'c') You should have a table for each entity and a table for the relationships. 只要类型a,b,c,d始终是父项,而类型foo和bar只能是子项(即“ foo”可能/将永远不是“ c”的父项),则您应该为每个实体都有一个表,并且关系表。 One table for parents (parent_id, parent_type), One table for children (child_id, child_type), and One table for relationships (parent_id, child_id).
一张表用于父母(parent_id,parent_type),一张表用于孩子(child_id,child_type)和一张关系表(parent_id,child_id)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.