SQL Server Primary Key和Clustered Index

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

  • 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__3213E83F3C0AD43D
go
ALTER 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-/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值