实际上,您不需要创建聚簇索引或主键,因为唯一索引和非唯一索引可以处理工作。SQL Server至少从1.1版开始就支持群集索引,但是主键只是程序员通过定义唯一索引来实施的“概念”。
但是,在大多数数据库中,主键和聚簇索引似乎都是有价值的概念。
让我们看一下SQL Server文档,以查看一些索引选项的部分说明,如下所示。
群集索引: https : //msdn.microsoft.com/en-us/library/ms190457.aspx
- 聚集索引根据它们的键值对数据行进行排序并将其存储在表或视图中。这些是索引定义中包含的列。
- 每个表只能有一个聚集索引
主键: https : //msdn.microsoft.com/en-us/library/ms190457.aspx
唯一索引: https : //msdn.microsoft.com/en-us/library/ms187019.aspx
这意味着您有关聚簇索引和主键的问题实际上是关于以下一些问题。请注意,并非每个表都受益于相同的索引编制计划。
我何时可以从与聚簇索引分开的主键中受益?
也许当聚集索引很宽时(例如5列文本信息,而主键很小(INT或BIGINT)),就像您正在描述的那样。
- 宽泛的聚集索引使您可以从索引中快速选择查询子集的行,这些查询子集可以从聚集索引(也称为表)中提供串行答案。例如,五列聚簇索引将支持扫描列C1,C2,C3,C4,C5或C1,C2,C3,C4等,直到C1。
- 注意:如果行很大,则在选择串行行集时可能会给您带来一些速度上的好处,特别是如果表中的其他列定期包含在结果集中时。
- 在那种情况下,您可以使用主键来实现参照完整性,以便提供所需的值作为外键来约束其他表中的行。PK很小,因此FK对引用表的大小影响很小。
- 但是,请注意,在具有“聚集索引”的表上创建的任何索引都将在此表上创建的其他索引中包括所有集群列。较宽的聚集索引将扩大该表上所有非聚集索引的大小。
您是否应该仅使主键成为聚簇索引?
如果您有一个小的主键(INT或BIGINT)并且它是聚簇索引,则聚簇列的开销相对较小。尽管在这种情况下,群集主键也将存在于此表的每个索引中,但要付出的代价比上面讨论的宽群集要小。
通常,该主键聚簇索引不会直接为串行选择许多行提供简便的方法。
既然您已经创建了集群主键,那么您曾经计划将其包括在集群索引中的那些其他列呢?
根据需要创建唯一(或非唯一)索引,以索引列C1,C2,C3,C4,C5的广泛搜索条件。该“模仿群集”索引中的值可以用作这5列的更快搜索路径。如果也有定期选择的一两个非索引列,则可以使用将它们包括在索引中 INCLUDE (Doctor_Name, Diagnosis_Synopsis)
。
尽管我发现简单的聚集索引和主键很有用,但仍有一些充分的理由考虑是否在表或数据库中使用它们。
您是否完全需要聚集索引?
如果创建索引(唯一索引和非唯一索引)并定义主键而没有成为聚集索引的开销,则可能会发现较窄的索引可以为您提供查询所需的内容。
聚集索引和主键中有一些有用的行为,但是请记住,实际上最重要的是索引。设计索引策略时要考虑到应用程序的实际情况。也许OneBigTable
需要与大多数表使用不同的索引策略。
如果没有聚簇索引,您的数据将与行标识符(RID)一起存储为堆,这根本不是一个好的搜索机制。但是,如前所述,您可以创建唯一索引和非唯一索引来处理查询。
现在,您需要考虑堆:
堆和索引: https : //msdn.microsoft.com/en-us/library/hh213609.aspx
- 将表存储为堆时,通过参考行标识符(RID)来标识各个行,该行标识符由文件号,数据页号和页面上的插槽组成。行ID是一个小型高效的结构。(但这不是索引。)
- 有时,当总是通过非聚簇索引访问数据且RID小于聚簇索引键时,数据架构师会使用堆。
但是,如果您在大数据集中也有一些“热点”,那么您也可以查看另一种类型的索引:
筛选的索引: https : //msdn.microsoft.com/zh-cn/library/cc280372.aspx
但是,如果您有兴趣考虑完全跳过主键和聚簇索引的可能性,则可以阅读下面链接的Markus Winand的文章。他通过一些代码示例演示了其原因,以表明有时放弃使用这些功能可能是个好主意。
http://use-the-index-luke.com/blog/2014-01/unreasonable-defaults-primary-key-clustering-key
但这一切最终都回到了理解您的应用程序以及设计代码,表,索引等以适合您正在执行的工作的角度。