簡體   English   中英

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. 表只能包含一個聚簇索引,主鍵可以是聚簇/非聚簇索引。
  2. Unique Key也可以是聚簇/非聚簇索引,下面是一些示例

場景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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM