2009-06-22 54 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