主鍵就是聚集索引嗎?


前言

  最近在一次面試中,討論了一個這樣的問題:主鍵和索引有什么區別?當時我的回答是這樣的:“主鍵就是加了唯一性約束的聚集索引。” “你確定你所說的是對的?” 面試官反問到。 “應該是對的。” 我不加思索地回答道。 “你回去后研究一下這個問題吧。”

  難道我真的錯了?

第一次嘗試

  當問題出現時,請用事實支持你的觀點。

  首先,必須了解一些基本知識:對於一張表來說,聚集索引只能有一個,因為數據真實的物理存儲順序就是按照聚集索引存儲的。基於這個原理,現在可以用這樣的方案來測試:對一張表設置一個主鍵, 之后再建立一個聚集索引,假如聚集索引能創建成功, 表明主鍵就不是聚集索引, 如果不可以建立聚集索引,就表明主鍵是聚集索引。

復制代碼
--建立一張TABLE 同時設置主鍵
CREATE TABLE student
(    
    stud_id  INT IDENTITY(1,1) NOT NULL,
    stud_name NVARCHAR(50) NOT NULL,    
    CONSTRAINT pk_student PRIMARY KEY(stud_id)    
);
復制代碼

  接下來就嘗試對這張表建立一個聚集索引吧。

CREATE CLUSTERED INDEX index_stud_name ON student(stud_name);

  執行這條語句的時候,SQLServer的消息框彈出了這樣的處理信息:“無法對 表 'student' 創建多個聚集索引。請在創建新聚集索引前刪除現有的聚集索引 'pk_student'。"

  是不是我已經勝出了?

進一步思考

  很大程度上,我應該對上述結果感到很滿意的。但謹慎的思維提醒我:會不會自己遺漏了什么東西?

  來看一下關於主鍵的定義吧,主鍵是表中的一個字段或多個字段,用來唯一地標識表中的一條記錄。唯一性是主鍵最主要的特性。在查閱建立主鍵的方法的時候, 一個之前被我完全忽略的創建方式突然出現在我的眼前, 在建立主鍵的時候可以聲明為CLUETERED(聚集)或NONCLUETERED(非聚集)!也就是說主鍵也可以聲明為非聚集索引,如下:

復制代碼
CREATE TABLE student
(
    stud_id INT IDENTITY(1,1) NOT NULL,
    stud_name NVARCHAR(20) NOT NULL,
    CONSTRAINT pk_student PRIMARY KEY NONCLUSTERED (stud_id)
);
復制代碼

  在SQLServer中,主鍵的創建必須依賴於索引,默認創建的是聚集索引,這就解釋了在上面的嘗試中為什么表中已建立了聚集索引。

  可見,真的是我錯了。

后續

  園子里的朋友提到一個觀點,就是跟着主鍵而創建的索引可以被單獨刪除,經我測試過,這是不可以的。

--執行刪除索引語句
DROP INDEX pk_student ON student

  SQLServer的消息框會彈出這樣的提示信息:”不允許對索引 'student.pk_student' 顯式地使用 DROP INDEX。該索引正用於 PRIMARY KEY 約束的強制執行。“

  如果對索引執行強制刪除的話,如下圖操作:

  

  結果是可以刪除的,但主鍵也會被跟着一起刪除,所以主鍵必須依賴於索引的觀點暫時是正確的。

參考:主鍵就是聚集索引嗎?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM