2009-06-22 53 views
14

重複:Many to Many Relation Design - Intersection Table Design使用組合鍵?或者總是使用代理鍵?

如果我有這些表(* =主鍵):

user 
    id* 
    name 

group 
    id* 
    name 

這是更好?

user_group 
    user_id* 
    group_id* 

或者這樣更好嗎?

user_group 
    id* 
    user_id 
    group_id 
+0

更好的是主觀的。兩者都可以正常工作。我個人的投票將是複合鍵,但又是個人喜好。 – 2009-06-22 21:29:56

+0

這是關於SO的其他幾個問題的重複。這是一個合理的問題,但之前已經提出並回答過。 – 2009-06-22 23:39:34

+4

被指示爲重複的鏈接有一個接受的答案,並不能真正回答這個問題。 – 2009-06-23 01:38:51

回答

10

我總是投票儘可能窄,靜態(永遠不會改變)的鍵,因此我通常贊成代理INT作爲複合鍵上的鍵。

如果你想從另一個表中引用一個複合鍵,你總是要指定多個條件 - 這可以得到有時相當笨拙!

還檢查了其中的一些環節:

(當然,其他人可能會張貼至少10個鏈接PRO自然鍵:-))

使用代理鍵沒有什麼壞處 - 去爲它! :-)

馬克

+0

在此示例中,UserId和GroupId不是自然鍵。它們是每個引用代理的外鍵。在這種情況下甚至不會出現自然鍵的問題。 – 2009-06-23 09:54:38

10

給予比既USER_ID和GROUP_ID已經代理鍵,從而保證是唯一的(給定適當執行該應用程序的),增加第三ID是完全冗餘的。

除非你使用某種ORM(可惜)通常會使組合鍵的處理更加複雜。在這種情況下,您必須評估冗餘成本與使用所選ORM進行開發的難易程度。

+0

但在需要更新的情況下,例如。比如改變特定用戶的組ID,那麼很難更新組合鍵。不是嗎? – Anand 2015-10-06 08:42:10

10

每當我從連接表中省略代理主鍵時,我就後悔了。這似乎是當我開始編寫代碼來管理具有代理主鍵的關係時非常方便。我通常遵循Active Record模式,並使用ASP.NET MVC,因此您的里程可能會有所不同。在MVC世界中,擁有一個可以放在URL末尾的單個id密鑰是非常有利的。

1

我通常會同意Vinko,但是如果您使用的是ORM,比如Hibernate,那麼如果您將所有內容都替換爲代理鍵,那麼它可以是一個更快樂的關係(在您和Hibernate之間)。

3

我通常建議「人造鑰匙」(你叫什麼叫「代理」),因爲,因爲他們是DB外基本無意義的,你能保證他們將永遠不會有變化,由於外部環境(而各種關於一個實體的其他數據可能會)。

但是,您的user_group表是一種典型的「兩個外鍵和全部」安排,用於實現多對多關係,這是一種不同的情況 - 所討論的兩個外鍵與您的控制一樣多代孕會。非實體的代理鍵,即一個只存在代表一點點關係的行,基本上只是個體重 - 我建議丟掉它。

3

第一個例子就足夠了。即使您要將屬性添加到多對多表結構中(如is_main_grp等),但在鏈接表中不需要代理,並且您可能總是希望在user_id上有一個唯一約束,無論如何,我們需要group_id

只有你掛在鏈接關係的其他多到一的關係(如標籤),THEN我會考慮在user_group爲表替代,我也不會做,直到這是一個要求(因爲替代品相對容易添加):

user 
    id* 
    name 

group 
    id* 
    name 

user_group 
    id* 
    user_id 
    group_id 
    is_main_grp 

user_group_tags 
    user_group_id* 
    tag_id* 

tags 
    id* 
    tag_txt