国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

主鍵與聚集索引

2024-07-21 02:46:00
字體:
來源:轉載
供稿:網友
主鍵與聚集索引

在今天的文章里我想談下SQL Server里非常重要的話題,當人們第一次使用SQL Server時是最會混淆的。即主鍵約束(PRimary Key constraint)和聚集索引(Clustered Index)的區別。

什么是主鍵(Primary Key)

首先讓我們談下主鍵約束本身。顧名思義它只是個約束,使用這個約束你告訴SQL Server你想在特定列或特定一組列有唯一值。下列代碼顯示了一個非常簡單的表定義,在第1個Col列指定了主鍵約束。

1 CREATE TABLE Foo2 (3     Col1 INT NOT NULL PRIMARY KEY,4     Col2 INT NOT NULL,5     Col3 INT NOT NULL6 )7 GO

現在當你往表里插入記錄,SQL Server確保在Col列總有唯一值。如果你嘗試插入重復值,SQL Server返回錯誤信息。

1 -- Try to insert a duplicate value2 INSERT INTO Foo Values (1, 1, 1), (1, 2, 2)3 GO

主鍵約束本身在邏輯層定義——你就告訴SQL Server你想在特定列有唯一值。但SQL Server也在物理層強制那個唯一性——你存儲你的表數據的數據結構里。在SQL Server情形里,唯一性使用索引結構在屋里層強制執行——使用聚集索引(Clustered Index)非聚集索引(Non-Clustered Index)。我們來詳細看下。

主鍵約束(Primary Key constraint)的強制執行

當你指定主鍵約束時,SQL Server在物理層默認通過使用唯一聚集索引(Unique Clustered Index)來強制執行。當你查看sys.indexes時,你會看到SQL Server內部已生成唯一聚集索引來強制執行主鍵約束。

1 -- SQL Server generates by default a Unique Clustered Index2 SELECT * FROM sys.indexes3 WHERE object_id = OBJECT_ID('Foo')4 GO

我已經說過,默認是創建唯一聚集索引。你也可以使用如下代碼所示的唯一非聚集索引來強制執行主鍵約束。

1 -- Enforces the Primary Key constraint with a Unique Non-Clustered Index2 CREATE TABLE Foo13 (4     Col1 INT NOT NULL PRIMARY KEY NONCLUSTERED,5     Col2 INT NOT NULL,6     Col3 INT NOT NULL7 )8 GO

當你指定主鍵約束時,你可以指定下列2個選項:

  • CLUSTERED
  • NONCLUSTERED

CLUSTERED選項是默認的,因此你比需要指定它。當你再次查看sys.indexes時,現在你會看到在你面前有一個堆表(heap table)(沒有聚集索引定義的表),SQL Server已經生成另外的唯一非聚集索引來強制執行主鍵約束。

1 -- SQL Server has generated now a Unique Non-Clustered Index to2 -- enforce the Primary Key constraint3 SELECT * FROM sys.indexes4 WHERE object_id = OBJECT_ID('Foo1')5 GO

主鍵不等于聚集索引

因此在SQL Server里并不意味著主鍵和聚集索引總是一樣的。默認是一樣的,但你可要修改這個如果你想要的話。主鍵約束總是在邏輯層,索引結構在是物理層來強制約束本身。

現在的問題是什么時候使用唯一非聚集索引來強制主鍵約束是有意義的?在上個月我寫了一篇自增長的聚集鍵值不會擴展的文章,里面談到了所謂的最后頁插入閂鎖競爭(Last Page Insert Latch Contention)問題:在SQL Server里,像INT IDENTITY列這樣的自增長的聚集鍵列不會擴展(Scale)。

如果你想解決這個問題,或許在隨機值上物理聚集/排序你的表數據——像UNIQUEIDENTIFIER列。在這個情況下,你還可以使用在原始的自增長鍵列上使用主鍵約束,但它是使用唯一非聚集索引來強制的,在隨機鍵列上聚集你的表。下面代碼顯示了這個方法。

 1 -- Create the Primary Key constraint on an ever-increasing 2 -- key column 3 CREATE TABLE Foo2 4 ( 5     Col1 INT NOT NULL PRIMARY KEY NONCLUSTERED, 6     Col2 UNIQUEIDENTIFIER NOT NULL, 7     Col3 INT NOT NULL 8 ) 9 GO10 11 -- Create the Clustered Index on a random key column12 CREATE UNIQUE CLUSTERED INDEX ci_Col2 ON Foo2(Col2)13 GO

當你再次查看sys.indexes時,現在你會看到你已經創建了聚集和非聚集索引。但只有非聚集索引用來強制主鍵約束。

1 -- Now we have a Clustered and Non-Clustered Index2 SELECT * FROM sys.indexes3 WHERE object_id = OBJECT_ID('Foo2')4 GO

小結

在SQL Server里,主鍵約束和聚集索引并不一樣的。默認SQL Server使用唯一聚集索引來強制主鍵約束。但如果你想要的話,你可以使用唯一非聚集索引來代替。但這個方法默認是沒有太大意義,因為你需要處理相關問題(最后頁插入閂鎖競爭)來使用這個方法。

感謝關注!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 卓资县| 定边县| 漠河县| 河津市| 新沂市| 札达县| 开江县| 唐山市| 蚌埠市| 定安县| 黑水县| 田林县| 辛集市| 柏乡县| 东乡族自治县| 射阳县| 龙泉市| 松滋市| 正镶白旗| 滦平县| 柘城县| 昌黎县| 万年县| 海原县| 安徽省| 龙口市| 洛阳市| 泾源县| 桦川县| 公主岭市| 闵行区| 平定县| 临夏市| 禄丰县| 抚顺市| 东阿县| 三亚市| 墨竹工卡县| 澄城县| 马公市| 宝山区|