mysql主鍵是聚集索引麼 主鍵就是聚集索引嗎?

2021-10-20 22:55:39 字數 1623 閱讀 8241

前言

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

難道我真的錯了?

第一次嘗試

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

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

--建立一張table 同時設定主鍵

create tablestudent

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 tablestudent

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 約束的強制執行。「

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

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

主鍵與聚集索引

參考文章 主鍵與聚集索引 表通常具有包含唯一標識表中每一行的值的一列或一組列。這樣的一列或多列稱為表的主鍵 pk 用於強制表的實體完整性。在建立或修改表時,您可以通過定義 primary key 約束來建立主鍵。主鍵 primary key 來自msdn的描述 表通常具有包含唯一標識表中每一行的值的...

知識點 主鍵是否是聚集索引?

這個問題很刁鑽!答案是錯的。的確在mysql資料庫innodb引擎裡面,主鍵的確就是聚集索引。但是myisam引擎裡面主鍵也不是聚集索引。另外在sql server中還可以顯示的指定聚集索引。create table student stud id int identity 1,1 not null...

mysql非主鍵索引 主鍵索引和非主鍵索引的區別

1.什麼是最左字首原則?以下回答全部是基於mysql的innodb引擎 例如對於下面這一張表 如果我們按照 name 欄位來建立索引的話,採用b 樹的結構,大概的索引結構如下 如果我們要進行模糊查詢,查詢name 以 張 開頭的所有人的id,即 sql 語句為 select id from tabl...