要點:如果您想將用戶羣&存儲在一張表中,因爲它們共享(大多數)特徵,這是非常有效的。但是,這意味着在技術上一個組可以是用戶的成員,並且您不能在數據庫級別強制用戶可以在組中而不是其他人擔心:
1個表中的情景:
CREATE TABLE users_and_groups (id int...
CREATE TABLE group_members (
group_id,
user_id
FOREIGN KEY (group_id) REFERENCES users_and_group (id) -- no way to limit on only groups
FOREIGN KEY (user_id) REFERENCES users_and_group (id) -- no way to limit on only users
)
方案在2個表:
CREATE TABLE users (id int...
CREATE TABLE groups (id int...
CREATE TABLE group_members (
group_id,
user_id
FOREIGN KEY (group_id) REFERENCES groups (id) -- guarantees a group
FOREIGN KEY (user_id) REFERENCES users (id) -- guarantees a user
)
防守建立一個數據庫,這樣可以防止一大堆的傷害,如果在應用程序級別的錯誤出現。
但是,如果user
& group
實體共享大量數據(既可以例如自己的其他對象,有個人資料頁等),4臺解決方案可以進行得很順利:
CREATE TABLE users_and_groups (id, ...shared data...
CREATE TABLE users (users_and_groups_id, ...user specific data...
CREATE TABLE groups (users_and_groups_id, .. group specific data...
CREATE TABLE group_members (
group_id,
user_id
FOREIGN KEY (group_id) REFERENCES groups (users_and_groups_id) -- guarantees a group
FOREIGN KEY (user_id) REFERENCES users (users_and_groups_id) -- guarantees a user
)
這有幾個優點:
- 外鍵的情形之一的組或用戶allowd可以在1列。
- 在應用程序級別,這是經典遺傳:基座
users_and_groups
,並且兩個user
& group
延伸基類/表。
- 強制執行組或用戶仍然可以使用外鍵
- 如果用戶或組獲得特定數據,則不需要將列添加到對大部分記錄無用的表中,可以存儲在類型特定的表中。
一些缺點:
- 就不可能執行該實體可以是一個用戶或一組,但不兩者或無(類型更少)
- 除非你存儲冗餘列
type
(或is_group
/is_user
),確定一個實體是一個組還是一個用戶需要一個JOIN
,但由於這是在雙方的主鍵上,開銷應該很小
這完全取決於你期望你的應用程序現在和不久的將來做什麼。雖然我會傾向於在正常化方面犯錯。 –
@MikeBrant謝謝,你能提供一些例子,也許在答案?關於這個問題的思考對我來說很新,所以我甚至不知道什麼是可能的。 –
標記爲偏離主題將被遷移到[dba.se] – hjpotter92