2017-02-10 167 views
1

今天我遇到了一個場景,我觀察到SQL Server實際上允許我們在同一列上創建主鍵約束和唯一約束。我預計它不會在語法上拋出任何錯誤。定義在表的同一列上的主鍵約束和唯一約束

我測試了它,它似乎工作正常。

示例代碼:

CREATE TABLE testtable 
(
    id INT IDENTITY(1,1), 
    name VARCHAR(10), 

    CONSTRAINT PK_ID PRIMARY KEY (id), 
    CONSTRAINT uk_id UNIQUE (id) 
) 

我也看到,它創建了一個PK約束,唯一約束分開。

我想知道分別創建這個獨特密鑰的優勢是什麼?

隨着主鍵一直創建一個唯一的約束是否是一個好習慣?如果答案是「否」,那麼在什麼情況下會是有利的。

我覺得它是一個非常基本的問題,但我想得到一些專家的想法和建議。

謝謝。

+1

主鍵在定義上是唯一的。這是多餘的,我無法想象它只是額外的開銷。 – pmbAustin

+2

所有主鍵都是唯一的,但並非所有唯一索引都是主鍵。 –

回答

2

沒有優勢,唯一密鑰與羣集主鍵是冗餘的。

通常,唯一鍵用於強制執行不在主鍵上的唯一約束,或者需要與主鍵不同的鍵的外鍵。

+1

準確。我有這樣的觀點,即主鍵在後臺自動實施唯一鍵。當我看到我的一位同事以這種方式實施時,我只是好奇而已。 –

+0

SQL Server的優點和缺點是它可以讓您以各種各樣的方式執行所有操作。其中許多是冗餘和次優的。例如,您可以根據需要爲同一列組合定義相同的非聚集索引。讀取操作不會帶來任何性能優勢,顯着的性能缺陷或寫入以及顯着的空間增加。然而,人們一直這樣做(通常無意) –

+3

在SQL Server中,主鍵不一定是聚簇的。 –

4

唯一約束是作爲數據庫中的約束對象列出的唯一索引。

這將與您的聚集索引(您的主鍵在這種情況下)分開存在。

這可能有一些好處,例如,對於針對此表的其他表的外鍵查找,因爲創建的唯一索引將小於聚集索引(如果表中存在其他列)。

Adding nonclustered index on primary keys

Unique Constraints and Unique Indexes

我認爲你有困難時找到一個優勢,如果你的主鍵是不是也聚集鍵,在這種情況下,你會添加多餘的唯一非聚集索引(即使其中一個不是主鍵也是允許的)。

2

該問題已被編輯,使其他兩個答案有點誤導。該編輯刪除了主鍵的顯式(和多種冗餘)CLUSTERED聲明。

在SQL Server中,主鍵不一定是聚簇的。主鍵有兩個特點:

  • 他們NOT NULL
  • 他們是UNIQUE

在一些數據庫中,一個PRIMARY KEY聲明必然會產生一個聚集索引。在SQL Server中,這是默認行爲,但它不是必需的:

CLUSTERED | NONCLUSTERED

指示爲 PRIMARY KEYUNIQUE約束創建了聚簇索引或非聚簇索引。 PRIMARY KEY約束默認 到CLUSTEREDUNIQUE約束默認爲NONCLUSTERED

因此,UNIQUE索引對於PRIMARY KEY定義是多餘的。我只能想象有人會先創建它,然後決定讓該列成爲PRIMARY KEY,忘記刪除聚集索引。這可能發生的一個原因是,如果代碼使用INDEX提示,並且該索引具有明確的名稱。

+1

也可能是問題中的表格結構大大簡化了。在定義中包含所有其他列的id列上表示聚集的主鍵可能比唯一索引寬得多。對於某些查詢模式,增加一個唯一索引(這是如何實現唯一約束)可能會有好處。這肯定是獲得計數的更便宜的方法,例如,如果這些是SQL Server可以選擇的唯一兩個索引。 –