Cur*_*che 15 sql primary-key composite-primary-key
我想看一个例子:
是否有时候数据库的选择会对上述例子产生影响?
Aar*_*ght 34
这似乎是关于代理键的问题,代理键总是自动递增数字或GUID,因此是单个列,而不是自然键,它们通常需要多条信息才能真正独一无二.如果你能够拥有一个只有一列的自然键,那么这一点显然没有实际意义.
有些人会坚持只使用其中一种.花足够的时间使用生产数据库,您将了解到没有与上下文无关的最佳实践.
其中一些答案使用SQL Server术语,但这些概念通常适用于所有DBMS产品:
聚集索引. 当数据库只能附加到聚簇索引时,聚簇索引始终表现最佳 - 否则,数据库必须执行页面拆分.请注意,这仅适用于密钥是顺序的,即自动递增序列或顺序GUID.任意GUID可能会更糟糕的表现.
关系.如果你的关键是3,4,5列长,包括性格类型和其他非压缩数据,你会浪费巨大的空间量,然后,如果你要建立外键关系在其他20桌此键降低性能.
唯一性.有时候,你并不拥有真实自然的关键.也许你的表是某种日志,你可以同时获得两个相同的事件.或者,您的真实密钥类似于物化路径,只能在已插入行之后确定.无论哪种方式,您总是希望您的聚簇索引和/或主键是唯一的,因此如果您没有其他真正独特的信息,您别无选择,只能使用代理键.
兼容性. 大多数人永远不必处理这个问题,但如果自然键包含类似a的东西hierarchyid,那么有些系统甚至可能无法读取它.在这种情况下,您还必须创建一个简单的自动生成的代理键供这些应用程序使用.即使您在自然键中没有任何"怪异"数据,一些DB库在处理多列主键时也会遇到很多麻烦,尽管这个问题很快就会消失.
存储.许多使用数据库的人从不使用足够大的数据库来处理这个因素.但是当一个表有数十亿或数万亿行时,您将希望保留此表中可能的绝对最小数据量.
复制.是的,您可以使用GUID或顺序GUID.但GUID有自己的权衡取舍,如果由于某种原因你不能或不想使用GUID,那么多列自然键是复制场景的更好选择,因为它本质上是全球唯一的 -是的,你不需要一个特殊的算法来使它独特,它的定义是独一无二的.这使得分布式体系结构的推理变得非常容易.
插入/更新性能.代理键不是免费的.如果您有一组唯一且经常查询的列,则需要在这些列上创建覆盖索引; 索引最终几乎与表一样大,这会浪费空间,并且每次进行任何修改时都需要更新第二个索引.如果您有可能在表上只有一个索引(聚簇索引),那么您应该这样做!
这就是刚刚想到的东西.如果我突然想起别的什么,我会更新.
你几乎总是想要一个主键,所以我假设选择是选择现有的两列作为主键,或者创建一个新的自动递增 PK 并在两列上放置一个普通的唯一约束。
当你想要一个 2 列的主键时:
当你想要一个自动递增的主键时:
我认为将主键设为自动生成的键并在多列上创建 UNIQUE 约束和索引几乎总是更好(至少从应用程序开发人员的角度来看)。
我遇到了几种令人头疼的情况,因为 DBA 认为多列主键总是足够的,而未来的需求变化证明这是不正确的。