2009-02-07 112 views
7

我一直在想,在SQL Server的M2M表中设置PK的最佳实践或后果是什么。例如:SQL Server中PK的最佳实践

我有2个表

  • 用户
  • 角色

我想提出一个新的表

  • UserRole的

其中有2场 角色ID &用户名

现在

应该我

  1. 创建UserRoleID的PK,使用户名和角色ID的FKS
    • 使PK的用户ID和角色ID,并将它们设置为FKS
    • 别的

我想知道每个选项的性能问题以及推荐的最佳做法。

回答

10

这些案例的标准程序是有两个索引。唯一的PK是两个字段合成的,首先具有较大基数的字段,即UserID;而第二个索引只有第二个字段(即RoleID)。

然后,集群中可能涉及更多多记录结果集的任何一个集群(即,如果查询每个用户多个角色或每个角色多个用户)。

+0

谢谢你不推荐一个无用的代理键! +1 – 2012-03-30 16:21:29

1

这取决于您是否希望将特定用户具有特定角色的任何其他含义挂起。如果没有,那么只需创建一个聚集的PK跨越两个字段。

为两者添加FK并将索引添加到第二个字段。请注意字段显示顺序。您是否更有可能检索用户所属的一组角色或特定角色中的一组用户?

0

这取决于你如何使用它们。大多数情况下,我将主键作为UserId和RoleId来确保它们是唯一的。这意味着同一个用户不能拥有相同的角色。

现在这就是“依赖”发挥作用的地方。如果您要将UserRole表链接到另一个表,那就是我创建UserRoleId主键的位置。并使UserId和RoleId成为一个唯一的约束。

造成这种情况的原因并不是在表上引用UserRole的UserId和RoleId不需要时,因为您分别链接到UserRoleId而不是用户表和角色表。

+0

因此,您每次想要获取任何有用的信息时,宁愿连接两个表,而不是向另一个表行添加额外的4个字节? – 2009-02-08 04:25:25

+0

@TomH。我明白你的意思,但是你什么时候换?如果你有一个m:m:m表格,你会把所有三列放在每个孩子身上。那么4或5呢?最终你的连接会变得非常丑陋,这就是为什么我们回避自然关键并且希望使用代理键来连接单列的原因 – 2012-03-30 16:28:44

2

将PK声明为(UserID,RoleID)。(注:顺序是重要的)

申报的用户ID作为FK与参考用户表。 将角色ID声明为具有对角色表的引用的FK。

运气好的话,你的DBMS会给你(用户ID,角色ID),一个综合指数的顺序。

运气好的话会加快用户和角色之间的联接。一个好的数据库管理系统会为你提供一个合并连接,除了连接条件以外没有任何限制。假设角色数量很少,三路连接的运行速度也相当快。

当你加入和的UserRole角色,没有用户加入,你会发现它的缓慢,令人失望。你多久做一次,在这种情况下速度有多重要?如果它很重要,可以在RoleID上创建一个索引。

0

避免复合PK,把一个唯一索引上的两个FKS(似乎在这种情况下是合适的)。在这种情况下不是问题,但要保持一致。必须记住在写入查询时处理多个字段以加入是一件痛苦的事情。如果您的组合键必须由日期时间,字符或其他类型的字段组成,则性能会受到影响。