Database design 复合主键与否?
这就是让我困惑的地方。我经常在数据库表中使用复合主键。这种方法不好的一面是,当我删除或编辑条目时,我有相当多的额外工作。然而,我觉得这种方法符合数据库设计的精神 另一方面,我的一些朋友从不使用复合键,而是在表中引入另一个“id”列,而所有其他键都只是fk。在编写删除和编辑过程时,它们的工作量要少得多。然而,我不知道它们如何保持数据项的唯一性 例如:Database design 复合主键与否?,database-design,composite-primary-key,Database Design,Composite Primary Key,这就是让我困惑的地方。我经常在数据库表中使用复合主键。这种方法不好的一面是,当我删除或编辑条目时,我有相当多的额外工作。然而,我觉得这种方法符合数据库设计的精神 另一方面,我的一些朋友从不使用复合键,而是在表中引入另一个“id”列,而所有其他键都只是fk。在编写删除和编辑过程时,它们的工作量要少得多。然而,我不知道它们如何保持数据项的唯一性 例如: 方式1 方式2 哪条路更好?使用第二种方法的缺点是什么?有什么建议吗?我个人更喜欢你的第二种方法(几乎100%的时候都会使用它)-引入一个代理ID字
方式1 方式2
哪条路更好?使用第二种方法的缺点是什么?有什么建议吗?我个人更喜欢你的第二种方法(几乎100%的时候都会使用它)-引入一个代理
ID
字段
为什么?
- 使引用您的表的任何表的工作都更加轻松-连接条件非常简单,只需一个ID列(而不是一直需要连接的2、3或更多列)
- 由于任何引用您的表的表只需要携带一个
作为外键字段,而不是复合键中的几列,因此使用起来更加方便ID
- 由于数据库可以处理唯一
列的创建(使用ID
),因此使生活更加轻松INT-IDENTITY
CREATE UNIQUE INDEX UIX_WhateverNameYouWant
ON dbo.ProxUsingDept(fkProx, fkDept)
现在,您的表保证在您的表中永远不会有重复的
(fkProx,fkDept)
——问题解决了 在某些情况下,如M:N连接表,复合键最有意义(如果性质或M:N链接发生变化,您将不得不重新编辑此表) 您会问以下问题:
但是,我不知道他们是怎么做的
保留数据项的唯一性
可以通过在列上声明单独的复合唯一索引来保持唯一性,否则这些列将形成自然主键
哪条路更好
不同的人有不同的观点,有时观点强烈。我想你会发现更多的人使用代理整数键(这并不是说它是“正确的”解决方案)
使用网络的坏处是什么
第二种方法
以下是使用代理密钥的一些缺点:
我知道这篇文章发表已经很久了。但是我不得不遇到一个类似的情况,关于复合键,所以我张贴我的想法 假设我们有两个表T1和T2 T1有C1列和C2列 T2有C1、C2和C3列 C1和C2是表T1的复合主键和表T2的外键
假设我们对表T1使用了一个代理键(T1_ID),并将其用作表T2中的外键,如果表T1的C1和C2的值发生变化,那么在表T2上强制执行referential ingegrity约束是额外的工作,因为我们只查看表T1中的代理键,该代理键的值在表T1中没有变化。这可能是第二种方法的一个问题。请查看@askmo。所以让我把这个弄对。为了简化编码,您需要添加(a)一个自动增量列(b)和额外的索引吗?不考虑完整的非dat或非业务需求?不担心你的负面表现?迷失的航向(见拉里的答案)?@marc_。这就是当你让那些关心他们个人好恶的人;他们易于编码,设计“数据库”。而不是关注总体使用、性能、标准和关系能力的专业数据库设计师。行业正处于一个非常悲惨的状态。@PerformanceDBA:我不同意你的说法-我总是喜欢简单的INT代理键,而不是复杂的“自然”复合键,原因正是我提到的-易于使用和创建外键关系。我已经看到很多次,人们只是放弃创建FK约束,因为他们的PK是由6、10甚至更多列组成的复合怪物……(续)自然键——特别是自然复合键——使表更加脆弱。这是事实。每种约束方式都会使表变得更脆弱,但自然的组合键更脆弱,因为您将技术约束(PK)与业务约束(用户指定的唯一性)结合在一起。需求可以而且确实会发生变化,我怀疑您遇到过不止一种情况,自然复合键突然变成不再适合作为主键的东西。如果说“真正的”DBA是与总体使用有关的(或者,rather@PerformanceDBA:谢谢你尊重地表达了自己的个人观点。你可以放心,任何读到这篇文章的人都会对它给予应有的考虑。回答得好。永远,而不是有时可能需要向一些读者和所有回复者解释。曾孙子女到父母的信息丢失;IDs要求将曾孙子女到孙子孙女到子女到父母的信息连接起来。+1表示您反对使用代理密钥的第二个论点。(并不是说我反对代理密钥-实际上恰恰相反)比我说的更公平。你的DB作为堡垒的概念似乎
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
)
CREATE UNIQUE INDEX UIX_WhateverNameYouWant
ON dbo.ProxUsingDept(fkProx, fkDept)