当我可以在复合列上使用具有唯一约束的单个主键时,为什么要使用复合主键?

Why Composite Primary key when I can use Single Primary key with Unique constraints on composite columns?

我正考虑将我的表架构从单个主键更改为复合主键。

此更改将影响我的许多表以及为查询此类表而编写的 SQL 语句(尤其是连接查询)。

对复合键方法的好处进行了一些研究后,我发现一个主要卖点是它用于强制复合列的唯一性。

但是,我仍然可以保留我的单个主键表,然后添加唯一约束以强制对复合列进行唯一性,如下所示:

create table ... (
 id primary key not null,
 column1 ...
 column2 ...
 .
 .
 columnN ...
 unique(column1, column2) // added this line to my existing tables
)

现在回答问题:

这两种方法的好处是什么?

明确定义复合主键或使用对复合列具有唯一约束的单个主键。为什么?

您不需要主键来强制唯一性。您可以改用 unique 约束或索引。

我不喜欢复合主键。以下是一些原因:

  • 所有外键引用都必须以正确的顺序和匹配类型包含所有键。这使得定义这些表稍微麻烦一些。
  • 因为复合键包含在所有引用表中,这些表通常更大,导致性能较差。
  • 如果您决定要更改其中一个组件键的类型——比如将字符串的长度或 int 更改为 numeric——您必须修改很多还有很多桌子。
  • 连接表时,您必须包括所有键。如果你错过了一个。 . .嗯,代码在语法上是正确的,但结果是错误的。

有些情况下组合键是可以接受的,例如没有外键引用的表。即使在那些情况下,我使用合成密钥,但我完全理解另一个观点。

我将从戈登·利诺夫的“另一个角度”发言。

总的来说,我是“专业”复合键。

我认为合成键是一种经常被过度使用的优化技术,有时它会成为一种没有任何优点的悲观主义,只是因为程序员已经习惯了它。

过度使用合成密钥的示例

  • 有一个 table 对 int(4 字节)和 date(4 字节)字段具有唯一约束
  • 它们永远不会改变
  • 但无论如何有人添加了一个 uuid(16 字节)具有随机值的字段
  • 并在上面定义一个PK

我们来分析一下:

  • 算术:在每行上添加 16 个字节 + 索引成本不是优化而是悲观化
  • 代码:我不认为加一个AND真的很痛
  • 语义:自然键具有一定的商业价值,合成键 - 不是

不要为了论证而认为这是一个虚构的反例——我看到了很多这样的合成密钥。

备注:

一个。 uuid 键在某些情况下可能是合理的,我在

中描述了它们

乙。即使是 bigint(8 字节)代理键也好不了多少:它是每行 8 字节 + 索引成本是免费的。

C。危险场景:所有应用程序代码都是围绕合成键编写的,然后有一天有人偶然发现了唯一约束违规,并且他想到了一个“聪明”的想法如何“修复”它:删除唯一约束!麾!应用程序开始工作!严酷的事实是后来才意识到的。

别笑,后者我看了好几遍

合成密钥的可行案例

一个。 唯一约束中的很多字段。我考虑:2 个字段可以,3 个 - 一般,4-5 个 - 编写所有 AND 变得很麻烦并且代码容易出错,所以我会考虑合成键

乙。 唯一约束中字段的长度很大。例如。您在唯一约束中组合了 varcharuuid,合成整数键的作用类似于优化技术

C。 唯一约束中的数据更新频繁。然后合成密钥

D. 唯一约束的规则可以在系统生命周期内改变。您知道实体是相关的,但您希望该规则可以随着新的业务需求而改变。然后合成密钥将解决这个问题。

E. 数据仓库设计于Dimensional Modelling。此类数据库的设计从代理键的设计开始

F. 其他要求,例如需要对数据库中的所有实体进行细粒度授权

总结

我认为不存在适用于所有情况的通用规则table。

合成密钥有其成本:

  • 不拘一格
  • 分析需求
  • 做数学
  • 从编码角度考虑