简体   繁体   English

SQL Server中PK的最佳实践

[英]Best Practice for PK in SQL Server

I have been wondering what the best practices or ramifications are in setting up the PK in a M2M table in SQL Server. 我一直想知道在SQL Server中的M2M表中设置PK的最佳实践或后果是什么。 For instance: 例如:

I have 2 tables 我有2张桌子

  • Users 用户
  • Roles 角色

I am making a new table 我正在制作一张新桌子

  • UserRole UserRole的

Which has 2 fields RoleId & UserID 其中有2个字段RoleId和UserID

now should I 我现在应该

  1. create a UserRoleID as the PK and make UserID and RoleID the FKs 创建一个UserRoleID作为PK,并使UserID和RoleID成为FK
    • make the PK UserID AND RoleID and set them as FKs 制作PK UserID和RoleID并将它们设置为FK
    • something else 别的

I would like to know the performance issues with each of the options and what the recommended best practices are. 我想知道每个选项的性能问题以及推荐的最佳实践。

Standard procedure for these cases is to have two indexes. 这些案例的标准程序是有两个索引。 The unique PK is the two fields composite, with the field with the greater cardinality first, ie UserID; 唯一的PK是两个字段复合,首先是具有更大基数的字段,即UserID; and the second index with just the secondary field (ie RoleID). 和第二个索引只有辅助字段(即RoleID)。

Then cluster on whichever is likely to be involved in more multirecord result sets (ie if querying for multiple roles per user, or multiple users per role). 然后聚集在更多多记录结果集中可能涉及的任何一个(即,如果查询每个用户的多个角色,或每个角色多个用户)。

Declare the PK as (UserID, RoleID). 将PK声明为(UserID,RoleID)。 (Note: the order is important) (注意:顺序很重要)

Declare UserID as an FK with the reference to the Users table. 使用对Users表的引用将UserID声明为FK。 Declare RoleID as an FK with the reference to the Roles table. 将RoleID声明为FK,并引用Roles表。

With any luck, your DBMS will give you a composite index on (UserID, RoleID) in that order. 运气好的话,您的DBMS将按顺序为您提供(UserID,RoleID)的综合索引。

With any luck this will speed up joins between users and roles. 运气好的话,这将加速用户和角色之间的联接。 A good DBMS will give you a merge join for a join with no restrictions other than the join condition. 一个好的DBMS将为连接提供合并连接,除了连接条件之外没有任何限制。 A three way join should run pretty fast as well, assuming the number of roles is small. 假设角色数量很少,三向连接也应该运行得非常快。

When you join UserRoles and Roles, without joining in Users, you may find it's disappointingly slow. 当您加入UserRoles和Roles时,如果没有加入用户,您可能会发现它的速度令人失望。 How often do you do that, and how important is speed in this case? 你经常这样做,在这种情况下速度有多重要? If it is important, you can create an index on just RoleID. 如果它很重要,您可以仅在RoleID上创建索引。

It depends whether you expect to hang any other meaning to the fact that a specific user has a specific role. 这取决于您是否希望将特定用户具有特定角色的任何其他含义挂起。 If not then just create a clustered PK to span across the two fields. 如果没有,那么只需创建一个跨越两个字段的聚簇PK。

Add FKs for both and add an index to the second field. 为两者添加FK并向第二个字段添加索引。 Give some consideration to which order the fields should appear in. Are you more likely to be retrieving a set of roles a user belongs to or the set of users in a specific role? 考虑字段应该出现在哪个顺序。您是否更有可能检索用户所属的角色集或特定角色的用户集?

It depends on how you are using them. 这取决于你如何使用它们。 Most of the time I make the primary key as a UserId and a RoleId to make sure they are unique. 大多数时候,我将主键作为UserId和RoleId来确保它们是唯一的。 Meaning the same user cannot have the same role. 意味着同一个用户不能拥有相同的角色。

Now this is where the "depends" comes into play. 现在这就是“依赖”发挥作用的地方。 If you are going to link the UserRole table to another table, that is where I create the UserRoleId primary key. 如果要将UserRole表链接到另一个表,那就是我创建UserRoleId主键的位置。 And make the UserId and RoleId into a unique constraint. 并将UserId和RoleId变为唯一约束。

The reason for this is not to have on the table that references the UserRole have both a UserId and a RoleId when it is not needed because you are linking to the UserRoleId and not the User table and the role table respectively. 这样做的原因是在引用UserRole的表上没有不需要UserId和RoleId的表,因为您分别链接到UserRoleId而不是User表和角色表。

Avoid the composite PK and put a unique index on the two FKs (Seems appropriate in this instance.). 避免使用复合PK并在两个FK上放置一个唯一索引(在本例中似乎是合适的)。 Not an issue in this case, but be consistent. 在这种情况下不是问题,但要保持一致。 Having to remember to address the multiple fields to join on when writing queries is a pain. 在编写查询时必须记住要处理要加入的多个字段是一件痛苦的事。 If your composite key has to be made up of datetime, char or other types of fields, performance takes a hit. 如果您的复合键必须由datetime,char或其他类型的字段组成,则性能会受到影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM