1

我有一种情况,一个特定的子对象可能有多个不同类型的父对象。例如,一个对象foo可能是一个或多个对象的子对象。此外,我还有一个对象,它也可能是一个或多个, , 或对象的子对象。在 SQL 中对此建模的正确方法是什么?abcbarabc

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 7or之类的问题Find all the children of parent 4,但我读过一些建议,基本上说永远不要为父/子关系创建通用表。

有人可以阐明执行此操作的最佳方法吗?为什么?可以安全地假设该表中的行数永远不会超过几百万行。

4

2 回答 2

1

我建议您的解决方案 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_tableID 引用。您不一定需要这些表中的 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

您可能还想阅读:

于 2013-07-15T23:30:56.883 回答
0

只要类型 a、b、c、d 始终是父级,并且类型 foo 和 bar 只能是子级(即 'foo' 可以/永远不会是 'c' 的父级),您应该为每个实体都有一个表,并且关系表。父母一张表(parent_id,parent_type),一张孩子表(child_id,child_type),一张关系表(parent_id,child_id)。

于 2013-07-15T23:22:41.770 回答