Ole*_*Dok
0
database-design
sql-server
database-tuning
database-theory
我已经厌倦了向我们研发团队中的每个初级开发人员解释为什么他应该使用主键以及如何使用。所以我决定写一个小白皮书,每个新开发人员都应该阅读。这是它的草稿。
免责声明:
- 我知道并理解聚集索引和主键之间的区别
- 在以下问题中,PRIMARY KEY 表示 PRIMARY KEY CLUSTERED,而 WITHOUT PRIMARY KEY 表示没有 PK 和 Clustered INDEX
- 请注意,这是面向初级而非 SQL 程序员的白皮书
- 他们所做的所有事情 - 在进入主要开发分支之前进行审查
- 我不会向他们解释——什么时候使用聚集索引和非聚集主键会有好处——否则我会陷入过早的优化地狱
问题是- 我还应该在文档中添加什么?可能是——我应该改些什么呢?更详细的解释是什么?
草稿来了:
- 主键必须约束数据库中的任何表。
- 如果没有 PK,一个表被认为是一个堆,而 SQL Server 对这种类型的数据的使用非常有限——我唯一应该说它是合适的——一个用于从 SQL Server 引擎外部快速批量加载数据的缓冲区。
- 避免使用自然主键。主要是因为它们的自然(高斯)分布。例如,在具有基于 Family 和 Name 的主键的 PhoneBook 表中,Smiths 和 Wilsons 将很多,而 Zimmerbergs 少得多,这表明,包含 Smiths 和 Wilsons 的页面将比其他页面更频繁地拆分,并且也更频繁地查询 - 这成倍增加性能影响。这会导致性能下降,因为主键的页面很满,并且大多数搜索都会命中 PK 的稀疏页面。
此外,即使使用具有(我希望)扁平分布的 SSN 或 ID Number,因为 PK 也不能解决 PK 的页面拆分问题,因为这些数字没有任何组织顺序。
- 次要 - 自然 PK 通常是复合的。这会创建复合外键和宽索引,从而损害性能。所以, ...
- 避免使用复合 PK。使用简单代理 PK 和复合 UNIQUE 索引比使用多合一复合 PK 更好,因为它会导致复合 FK 和宽索引,这是由于声明,带有 PK 的表上的每个二级索引都必须包含整个 PK。
- 避免使用除整数或唯一标识符类型以外的代理主键
- 在数据库设计阶段,识别实体和相应的表非常重要,这些表可能有“无数”的行,或者表的键不仅必须是表范围唯一的,而且是数据库甚至世界唯一的,或者必须是通过这个键在几个跳表上与其他表连接 - 这个表最好有 UUID PK,其他表 - 普通整数,因为 SQL Server 很好地调整为使用整数 PK。
- 这两种类型可以保证向量分布(IDENTITY 或 NEWSEQUENTIALID())和单调序列。
- 主要的数据库设计规则 -花费 20 分钟进行深思熟虑的设计将在生产数据库的维护期间节省数天甚至数周的时间