复合主键与否?

时间:2011-01-19 15:35:20

标签: database-design composite-primary-key

这让我感到困惑。我经常在数据库表中使用复合主键。这种方法的不好的一面是,当我删除或编辑条目时,我还有额外的工作。但是,我觉得这种方法符合数据库设计的精神。

另一方面,有我的朋友,他们从不使用复合键,而是在表中引入另一个'id'列,而所有其他键只是FK。在编写删除和编辑过程时,它们的工作量要少得多。但是,我不知道它们如何保留数据条目的唯一性。

例如:
方式1

create table ProxUsingDept (
    fkProx int references Prox(ProxID) NOT NULL,    
    fkDept int references Department(DeptID) NOT NULL,    
    Value int,    
    PRIMARY KEY(fkProx,fkDept)
)

方式2

create table ProxUsingDept (
        ID int NOT NULL IDENTITY PRIMARY KEY
        fkProx int references Prox(ProxID) NOT NULL,    
        fkDept int references Department(DeptID) NOT NULL,    
        Value int
)

哪种方式更好?使用第二种方法有什么不好的方面?有什么建议吗?

4 个答案:

答案 0 :(得分:25)

我个人偏好你的第二种方法(并且几乎100%都会使用它) - 引入代理ID字段。

为什么?

  • 使任何引用表格的表格变得更轻松 - JOIN条件更简单只有一个ID列(而不是2,3或甚至更多列需要一直加入

  • 让生活变得更轻松,因为任何引用您的表的表只需要携带一个ID作为外键字段 - 而不是复合键中的几列

  • 让生活变得更轻松,因为数据库可以处理独特的ID列的创建(使用INT IDENTITY

  

然而,我不知道他们是怎么回事   保留数据条目的唯一性。

非常简单:在你原本用作主键的复合列上放一个UNIQUE INDEX!

CREATE UNIQUE INDEX UIX_WhateverNameYouWant 
   ON dbo.ProxUsingDept(fkProx, fkDept)

现在,您的表格保证您的表格中永远不会有一对重复的(fkProx, fkDept) - 问题已解决!

答案 1 :(得分:17)

您提出以下问题:

  

然而,我不知道他们是怎么回事   保留数据条目的唯一性。

可以通过在列上声明单独的复合UNIQUE索引来保留唯一性,否则这些索引将形成自然主键。

  

哪种方式更好?

不同的人有不同的意见,有时坚持不懈。我想你会发现更多的人使用代理整数键(不是那个使它成为“正确”的解决方案)。

  

使用它有什么不好的方面   第二种方法?

以下是使用代理键的一些缺点:

  1. 您需要一个额外的索引来维护自然主键的唯一性。

  2. 在选择数据以获取所需结果时,有时需要额外的JOIN(当您只使用复合自然键中的列满足查询要求时会发生这种情况;在这种情况下,您可以使用外键列而不是JOIN回到原始表。)

答案 2 :(得分:0)

有些情况如M:N连接表,其中复合键最有意义(如果性质或M:N链接发生变化,则无论如何都必须重新编写此表)。

答案 3 :(得分:-3)

我知道这篇文章发布后已经很长时间了。但是我不得不遇到关于复合键的类似情况,所以我发表了自己的想法。

假设我们有两个表T1和T2。

T1有C1和C2列。

T2具有列C1,C2和C3

C1和C2是表T1的复合主键和表T2的外键。

假设我们使用了表T1(T1_ID)的代理键并将其用作表T2中的外键,如果表T1的C1和C2的值发生变化,则强制执行参考不完整性是额外的工作对表T2的约束,因为我们只看表T1中的代理键,其值在表T1中没有变化。这可能是第二种方法的一个问题。