繁体   English   中英

在SQL中建模M:N关系的正确方法,其中父级可能是许多类型之一

[英]Proper way to model M:N relationship in SQL where parent may be one of many types

我遇到一个特定的子对象可能具有多个不同类型的父对象的情况。 例如, foo对象可以是abc对象中a或多个的子对象。 而且,我还有一个bar对象,它也可以是abc对象的一个​​或多个。 在SQL中对此建模的正确方法是什么?

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)每个父类型的唯一表:

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)每个孩子类型的唯一表:

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)每个组合的唯一表

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)我没有探索过的其他策略

对我来说,似乎A是最简单的查询和回答问题,例如“ Find all the parents of child 7或“ Find all the children of parent 4 ,但我读过一些建议,基本上说从不为父母/创建通用表儿童关系。

有人可以阐明这样做的最佳方法吗?为什么? 可以肯定地说,表中的行永远不会超过几百万行。

我建议您使用解决方案C的一种变体。对于每个M:N关系,您都需要有一个单独的M:N表(根据“ 第四范式”)

而且还要创建一个上表,以统一所有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

在每个子父表中, parent_type被限制为单个值。 parent_table对(parent_id,parent_type)具有唯一约束,并且每个子父表中的外键引用该唯一约束中的列。 因此,任何一个以上的子类型都不能引用parent_id。

然后,您的子M:N表仅需parent_table ID引用parent_table 这些表中不一定需要有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

您可能还喜欢阅读:

只要类型a,b,c,d始终是父项,而类型foo和bar只能是子项(即“ foo”可能/将永远不是“ c”的父项),则您应该为每个实体都有一个表,并且关系表。 一张表用于父母(parent_id,parent_type),一张表用于孩子(child_id,child_type)和一张关系表(parent_id,child_id)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM