使用复合键?或者总是使用代理键?

时间:2009-06-22 21:26:44

标签: database-design primary-key

  

重复: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

6 个答案:

答案 0 :(得分:10)

我总是投票选择尽可能窄的键,静态(永不改变),因此我通常喜欢代理INT作为复合键的键。

如果你想从另一个表中引用一个复合键,你总是需要指定几个条件 - 有时会变得非常笨重!

另请查看其中一些链接:

(当然,其他人可能会发布至少10个链接PRO自然键:-))

使用代理键没有坏处 - 去吧! : - )

马克

答案 1 :(得分:10)

鉴于user_id和group_id都已经是代理键,因此保证是唯一的(给定应用程序的正确实现),添加第三个id是完全多余的。

除非您使用某种ORM(可悲的是)通常会使复合键的处理变得更加复杂。在这种情况下,您必须使用所选ORM评估冗余成本与开发难易程度。

答案 2 :(得分:10)

每当我从连接表中省略代理主键时,我就会后悔。这似乎就像当我开始编写代码来管理具有代理主键的关系时非常方便。我通常遵循Active Record模式并使用ASP.NET MVC,因此您的里程可能会有所不同。在MVC世界中,拥有一个可以放在URL末尾的id密钥是非常有利的。

答案 3 :(得分:3)

我通常建议使用“人工钥匙”(你称之为“代理人”),因为它们在数据库之外基本没有意义,你可以保证他们永远不会因外部环境而改变(而各种各样的关于实体的其他数据可能很好。)

但是你的user_group表,一个典型的“两个外键,这就是所有”用于实现许多关系的安排,是一个不同的情况 - 有问题的两个外键就在你的下面作为代理人的控制权。非实体的代理键,即仅存在代表一点点关系的行,基本上只是载重量 - 我建议丢失它。

答案 4 :(得分:3)

第一个例子就足够了。即使您要向多对多表构造添加属性(如is_main_grp等),也不需要链接表中的代理,并且您可能总是想要一个唯一的无论如何,约束user_idgroup_id

只有你要在链接关系上挂起另一个多对一关系(比如标签),那么我会考虑在{ {1}}表,我不会这样做,直到它是一个要求(因为代理相对容易添加):

user_group

答案 5 :(得分:1)

我通常会同意Vinko,但是如果你正在使用ORM,比如Hibernate,那么如果你给所有东西一个代理键,那么你和Hibernate之间的关系可能会更快乐。