主键的最佳实践

时间:2015-08-01 18:51:32

标签: sql-server database primary-key

我知道使用Identity列作为主键的问题。我想我第一次在Brent Ozar的博客上看过它。基本上,最常访问的数据是最近输入的数据,并且随着标识列的递增,这往往会将所有数据库活动集中在数据库的最后一页上,从而导致大量争用和锁定。建议您的主键基于一些有意义的列(或列),以便数据在数据库的页面中更均匀地传播。

鉴于此,我正在尝试优化主键:

Request_ID int --1234, 2326, etc
Department nchar(2) -- 'MP', 'SS', 'FR', etc
Condition_ID int identity

Condition_ID是必需的,因为(Request_ID + Department)不是唯一的。 (Request_ID + Department)中可以有多个条件。

Condition_ID是唯一的(作为标识列),但仅使其成为主键会导致我上面提到的问题。 Request_ID虽然不是标识列,但仍然是序列号,也会导致同样的问题。

部门至少是变化的(FR,SS,MP,CS等)

所以,我的问题是:鉴于我必须使用什么,什么是一个好的主键组合,以避免我提到的问题?

将部门作为PK中的第一列,然后是Request_ID,然后是Condition_ID会有什么好处吗?

2 个答案:

答案 0 :(得分:0)

在Oracle中,您可以通过对索引进行散列分区来减少争用。例如,64的散列大小提供了一个很好的中间地带(A)相同块中的所有新行(争用太多)和(B)遍布整个地方的新行(物理I / O太多)。 / p>

你可以通过使用两个增量数字来做类似的事情。也就是说,计算mod(sequence1,64)并将其预先添加到sequence2,通过使用两列PK或通过乘法 -

class Resource {
    //whatever members are necessary
    public:
    //resource acquisition for which this object is responsible should be constrained to constructor(s)
    ~Resource() { //or virtual ~Resource() if inheritance desired
        //deal with resource cleanup
    }
};

此外,除非你的桌子有很多插入,否则这个争论虽然真实,但你可能不会担心这个问题。

答案 1 :(得分:0)

  

以便数据在数据库页面中更均匀地传播

因此,您可以识别将影响性能的主键属性。

  

什么是一个好的主键组合......?

根据您的数据大小,您提到的密钥组合,您是否看到任何性能差异?如果是这样,有多重要?最终,你必须根据你的应用程序对大小,速度,负载以及Bogdan Sahlean,Martin Smith和Dan Guzman在上述评论中提出的其他特征的需求找到合适的组合。

  

将部门作为PK中的第一列,然后是Request_ID,然后是Condition_ID会有什么好处吗?

取决于查询和数据大小。 PK选择将影响数据的存储方式,从而无需制作单独的索引,因为您可以根据PK获得聚集索引(免费)。

  

增量键是否与聚合键相同?

没有。如果您说的是SQLSERVER,则incremental是指添加,删除记录时服务器为该字段管理的自动增量值。聚合键是指形成该行的聚合键的列值的组合(通常用于唯一性)。在您的示例中,所有这些聚合都是唯一的(因此是PK /群集的候选者):

Condition_ID

Condition_ID + Department

Condition_ID + Department + Request_ID