![](/img/trans.png)
[英]Django 1.7 - SQL - Get data from One-To-Many relationship where relation may or may not exist
[英]Proper way to model M:N relationship in SQL where parent may be one of many types
我遇到一個特定的子對象可能具有多個不同類型的父對象的情況。 例如, foo
對象可以是a
, b
或c
對象中a
或多個的子對象。 而且,我還有一個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
,但我讀過一些建議,基本上說從不為父母/創建通用表兒童關系。
有人可以闡明這樣做的最佳方法嗎?為什么? 可以肯定地說,表中的行永遠不會超過幾百萬行。
我建議您使用解決方案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.