这让我感到困惑。我经常在数据库表中使用复合主键。这种方法的不好的一面是,当我删除或编辑条目时,我还有额外的工作。但是,我觉得这种方法符合数据库设计的精神。
另一方面,有我的朋友,他们从不使用复合键,而是在表中引入另一个'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
)
哪种方式更好?使用第二种方法有什么不好的方面?有什么建议吗?
答案 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索引来保留唯一性,否则这些索引将形成自然主键。
哪种方式更好?
不同的人有不同的意见,有时坚持不懈。我想你会发现更多的人使用代理整数键(不是那个使它成为“正确”的解决方案)。
使用它有什么不好的方面 第二种方法?
以下是使用代理键的一些缺点:
您需要一个额外的索引来维护自然主键的唯一性。
在选择数据以获取所需结果时,有时需要额外的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中没有变化。这可能是第二种方法的一个问题。