我遇到了一种情况,一个特定的子对象可能有多个不同类型的父对象。例如,一个foo
对象可能是一个或多个a
、b
或c
对象的子对象。此外,我还有一个bar
对象,它也可能是一个或多个a
、b
或者c
对象。在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
之类的问题的,但我读过一些建议,基本上是说永远不要为父/子关系创建通用表。
有没有人能告诉我们最好的方法和为什么?可以肯定的是,表中的行永远不会超过几百万行。
2条答案
按热度按时间6pp0gazn1#
我建议您使用解决方案C的变体。您需要为每个M:N关系使用一个单独的M:N表(按照Fourth Normal Form)。
而且还要创建一个超表来统一所有的a、b、c父类型,以便M:N表可以引用单个表,其中每个parent_id都被严格地分配了各自的类型。
在每个子父代表中,
parent_type
被限制为单个值。parent_table
对(parent_id,parent_type)具有唯一约束条件,并且每个子父代表中的外键引用该唯一约束条件中的列。因此,没有parent_id可以被多个子类型引用。然后,子M:N表只需要按ID引用
parent_table
。这些表中不一定需要parent_type列,但如果需要在(child_id,parent_type)上创建UNIQUE约束,以便每个子表只能有一个给定类型的父表,则需要这样做。您可能还想阅读:
2ledvvac2#
只要类型a、B、c、d始终是父项,而类型foo和bar只能是子项(即'foo'可能/永远不会是'c'的父项),则每个实体都应有一个表,关系也应有一个表。一个表用于父项(parent_id,parent_type),一个表用于子项(child_id,child_type),一个表用于关系(parent_id,child_id)。