[英]Clustered/non-clustered index on unique identifier column in SQL Server
[英]Is Unique key Clustered or Non-Clustered Index in SQL Server?
我是SQL Server的新手,在學習聚集索引時,我感到很困惑!
是唯一鍵聚簇還是非聚簇索引? 唯一鍵只保留列中的唯一值,包括null,因此根據這個概念,唯一鍵應該是聚簇索引,對吧? 但是當我閱讀這篇文章時,我對MSDN感到困惑
創建UNIQUE約束時,會創建唯一的非聚簇索引以默認強制執行UNIQUE約束。 如果表上的聚簇索引尚不存在,則可以指定唯一的聚簇索引。
請幫助我以更好的方式理解這個概念,謝謝。
在SQL Server索引中有三種強制唯一性的方法。
無論它們是群集還是非群集,都與使用這些方法中的索引是否聲明為唯一正交。
這三種方法都可以創建聚簇索引或非聚簇索引。
默認情況下,如果您沒有指定任何不同的唯一約束和唯一索引將創建非聚集索引(並且如果不存在沖突的聚簇索引,則默認情況下將PK創建為CLUSTERED
)但您可以為任何指定顯式指定CLUSTERED
/ NONCLUSTERED
他們
示例語法是
CREATE TABLE T
(
X INT NOT NULL,
Y INT NOT NULL,
Z INT NOT NULL
);
ALTER TABLE T ADD PRIMARY KEY NONCLUSTERED(X);
--Unique constraint NONCLUSTERED would be the default anyway
ALTER TABLE T ADD UNIQUE NONCLUSTERED(Y);
CREATE UNIQUE CLUSTERED INDEX ix ON T(Z);
DROP TABLE T;
對於未指定為唯一的索引,SQL Server將以任何方式靜默地使它們成為唯一的。 對於聚簇索引,可以通過將唯一文件附加到重復鍵來完成。 對於非聚簇索引,將行標識符(邏輯或物理)添加到密鑰以保證唯一性。
唯一索引可以是群集的也可以是非群集的。 但是如果你有可空列,則NULL值應該是唯一的(只有1行,其中column為null)。 如果要存儲多於1個NULL,則可以使用過濾器“where columnName not null”創建索引。
以及所提供的所有答案都非常有用,但我仍然想補充一些詳細的答案,以便我對其他人也有所幫助
場景1:主鍵將默認為聚簇索引
在這種情況下,我們將只創建主鍵,當我們檢查在表上創建的索引類型時,我們會注意到它已經自動創建了聚簇索引。
USE TempDB
GO
-- Create table
CREATE TABLE TestTable
(ID INT NOT NULL PRIMARY KEY,
Col1 INT NOT NULL)
GO
-- Check Indexes
SELECT OBJECT_NAME(OBJECT_ID) TableObject,
[name] IndexName,
[Type_Desc] FROM sys.indexes
WHERE OBJECT_NAME(OBJECT_ID) = 'TestTable'
GO
-- Clean up
DROP TABLE TestTable
GO
場景2:主鍵定義為非聚集索引
在這種情況下,我們將顯式定義主鍵作為非聚集索引,並將其創建為非聚集索引。 它證明了主鍵可以是非聚集索引。
USE TempDB
GO
-- Create table
CREATE TABLE TestTable
(ID INT NOT NULL PRIMARY KEY NONCLUSTERED,
Col1 INT NOT NULL)
GO
-- Check Indexes
SELECT OBJECT_NAME(OBJECT_ID) TableObject,
[name] IndexName,
[Type_Desc] FROM sys.indexes
WHERE OBJECT_NAME(OBJECT_ID) = 'TestTable'
GO
-- Clean up
DROP TABLE TestTable
GO
場景3:主鍵默認為非聚簇索引,另一列定義為聚簇索引
在這種情況下,我們將在另一列上創建聚簇索引,SQL Server將自動創建主鍵作為非聚集索引,因為在另一列上指定了聚簇索引。
-- Case 3 Primary Key Defaults to Non-clustered Index
USE TempDB
GO
-- Create table
CREATE TABLE TestTable
(ID INT NOT NULL PRIMARY KEY,
Col1 INT NOT NULL UNIQUE CLUSTERED)
GO
-- Check Indexes
SELECT OBJECT_NAME(OBJECT_ID) TableObject,
[name] IndexName,
[Type_Desc] FROM sys.indexes
WHERE OBJECT_NAME(OBJECT_ID) = 'TestTable'
GO
-- Clean up
DROP TABLE TestTable
GO
方案4:主鍵默認為聚簇索引,其他索引默認為非聚簇索引
在這種情況下,我們將在兩個表上創建兩個索引,但是我們不會在列上指定索引的類型。 當我們檢查結果時,我們會注意到主鍵自動默認為聚簇索引而另一列默認為非聚集索引。
-- Case 4 Primary Key and Defaults
USE TempDB
GO
-- Create table
CREATE TABLE TestTable
(ID INT NOT NULL PRIMARY KEY,
Col1 INT NOT NULL UNIQUE)
GO
-- Check Indexes
SELECT OBJECT_NAME(OBJECT_ID) TableObject,
[name] IndexName,
[Type_Desc] FROM sys.indexes
WHERE OBJECT_NAME(OBJECT_ID) = 'TestTable'
GO
-- Clean up
DROP TABLE TestTable
GO
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.