当我可以在复合列上使用具有唯一约束的单个主键时,为什么要使用复合主键?
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
变得很麻烦并且代码容易出错,所以我会考虑合成键
乙。 唯一约束中字段的长度很大。例如。您在唯一约束中组合了 varchar
和 uuid
,合成整数键的作用类似于优化技术
C。 唯一约束中的数据更新频繁。然后合成密钥
D. 唯一约束的规则可以在系统生命周期内改变。您知道实体是相关的,但您希望该规则可以随着新的业务需求而改变。然后合成密钥将解决这个问题。
E. 数据仓库设计于Dimensional Modelling。此类数据库的设计从代理键的设计开始
F. 其他要求,例如需要对数据库中的所有实体进行细粒度授权。
总结
我认为不存在适用于所有情况的通用规则table。
合成密钥有其成本:
- 不拘一格
- 分析需求
- 做数学
- 从编码角度考虑
我正考虑将我的表架构从单个主键更改为复合主键。
此更改将影响我的许多表以及为查询此类表而编写的 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
变得很麻烦并且代码容易出错,所以我会考虑合成键
乙。 唯一约束中字段的长度很大。例如。您在唯一约束中组合了 varchar
和 uuid
,合成整数键的作用类似于优化技术
C。 唯一约束中的数据更新频繁。然后合成密钥
D. 唯一约束的规则可以在系统生命周期内改变。您知道实体是相关的,但您希望该规则可以随着新的业务需求而改变。然后合成密钥将解决这个问题。
E. 数据仓库设计于Dimensional Modelling。此类数据库的设计从代理键的设计开始
F. 其他要求,例如需要对数据库中的所有实体进行细粒度授权。
总结
我认为不存在适用于所有情况的通用规则table。
合成密钥有其成本:
- 不拘一格
- 分析需求
- 做数学
- 从编码角度考虑