SQL Server Primary Key和Clustered Index

来源:互联网 发布:网络与新媒体论文选题 编辑:程序博客网 时间:2024/05/01 20:09

       我们都知道,一个表或者视图可以包括下面两种类型的索引:

  • Clustered index
  1.  Clustered index 基于索引列来排序和存储数据行。既然数据行只能按照一种顺序来存储,那么每个表理所当然,只能有一个聚集索引。
  2.  只有当表包含Clustered index的时候,表里的数据行才会按序存储。有Clustered index的表被称作聚集表,如果一个表没有Clustered index,那个它的数据行被存储在一个叫做堆的无序结构中。
  • Non-Clustered index
  1.  Non-Clustered index 有自己的独立存储结构。它包含索引列的值,并且每组值有个指针指向包含这组值的数据行。
  2.  索引里面的指针被称作行定位器。它的结构取决于数据页是保存在堆上,还是聚集表。如果是堆,则行定位器指向数据行,反之,它是一个聚集索引的Key。
  3. 因为索引有900字节等限制,可以通过include columns语法,将非索引列添加到Non-Clustered index中。

      选择列作为Clustered index的时候,一般需要保证下面四点

  1.  栏位窄,即 字节长度越少越好
  2.  唯一, 避免SQL Server 为重复的键值添加"uniqueifier"
  3. 理想情况下,产生后从不变更
  4. 值最好一直递增,避免写的效能下降

    在创建Table设定主键的时候,SQL Server会自动创建一个对应的Clustered Index。如果使用Microsoft SQL Server Management Studio工具,发现这个Clustered Index只能删除,不能通过界面进行修改。这让人误以为在主键上只能建立Clustered Index, 实际上却不是这样的。

   如果通过Script 创建,我们可以指定在主键上建立Clustered / Non-Clustered Index。示例如下:

CREATE TABLE [dbo].[table_1]([id] [int] NOT NULL,PRIMARY KEY ([id] ASC))CREATE TABLE [dbo].[table_2]([id] [int] NOT NULL,PRIMARY KEY NONCLUSTERED ([id] ASC))

table_1 上将默认建立Clustered Index, table_2则建立的是Non Clustered Index。


对于已经建立主键的Table,如果要改成Non Clustered Index, 可以先删除主键,再重新创建成Non Clustered Index

ALTER TABLE [dbo].[table_1]DROP CONSTRAINT PK__table_1__3213E83F3C0AD43DgoALTER TABLE [dbo].[table_1] ADD CONSTRAINT PK__table_1__3213E83F3C0AD43D     PRIMARY KEY NONCLUSTERED (id)go

在创建Table的时候,也可以同时设定一个栏位为主键,而另外一个栏位是Clustered index.

CREATE TABLE [dbo].[table_3](id INT NOT NULL PRIMARY KEY,col1 INT NOT NULL UNIQUE CLUSTERED)go


综上所述,主键只是一个Constraint, 主键上能够建立Clustered / Non-Clustered Index,  当然通用的最佳实践是把主键创建为Clustered Index。


参考资料:

https://www.simple-talk.com/sql/learn-sql-server/effective-clustered-indexes/

http://www.sqlserverlogexplorer.com/overview-of-cluster-and-noncluster-index/

http://www.sqlservercentral.com/blogs/practicalsqldba/2013/03/14/sql-server-part-4-explaining-the-non-clustered-index-structure-/

0 0
原创粉丝点击