SQL Server Primary Key和Clustered Index
阿新 • • 發佈:2019-02-05
我們都知道,一個表或者檢視可以包括下面兩種型別的索引:
- Clustered index
- Clustered index 基於索引列來排序和儲存資料行。既然資料行只能按照一種順序來儲存,那麼每個表理所當然,只能有一個聚集索引。
- 只有當表包含Clustered index的時候,表裡的資料行才會按序儲存。有Clustered index的表被稱作聚集表,如果一個表沒有Clustered index,那個它的資料行被儲存在一個叫做堆的無序結構中。
- Non-Clustered index
- Non-Clustered index 有自己的獨立儲存結構。它包含索引列的值,並且每組值有個指標指向包含這組值的資料行。
- 索引裡面的指標被稱作行定位器。它的結構取決於資料頁是儲存在堆上,還是聚集表。如果是堆,則行定位器指向資料行,反之,它是一個聚集索引的Key。
- 因為索引有900位元組等限制,可以通過include columns語法,將非索引列新增到Non-Clustered index中。
選擇列作為Clustered index的時候,一般需要保證下面四點
- 欄位窄,即 位元組長度越少越好
- 唯一, 避免SQL Server 為重複的鍵值新增"uniqueifier"
- 理想情況下,產生後從不變更
- 值最好一直遞增,避免寫的效能下降
在建立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。
參考資料: