1. 程式人生 > >SQL Server Primary Key和Clustered Index

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。

參考資料: