2012-04-21 83 views
42

我有一個名爲countries的表,我通過在SQL Server 2008 R2上創建「唯一鍵」類型的「索引/鍵」來定義country_name列爲唯一鍵。唯一鍵與SQL Server 2008上的唯一索引

但我有以下問題:

  1. 將創建一個類型的「索引/鍵」「唯一鍵」自動創建該列的一個非聚集索引?
  2. 如果我將類型從「Unique Key」更改爲「Index」,並且我將IsUnique的值保持爲「Yes」,那麼會有什麼區別嗎?
  3. 那麼爲什麼有兩個選項「Unique Key」和「Index」我認爲兩者是一樣的?

回答

59

一個獨特的約束是作爲一個唯一的索引在幕後實現的,因此它如何指定它並不重要。我傾向於將其實現爲:

ALTER TABLE dbo.foo ADD CONSTRAINT UQ_bar UNIQUE(bar); 

有人創建了一個唯一索引,例如,

CREATE UNIQUE INDEX IX_UQ_Bar ON dbo.foo(bar); 

的差別是在意向 - 如果你創建的約束強制唯一性/業務規則,爲您營造一個約束,如果你這樣做是爲了幫助查詢性能,它可能是更合乎邏輯的創建獨特的索引。再一次,在封面下它是相同的實現,但你到達那裏的路可能有助於記錄你的意圖。

我認爲有多個選項可以遵循先前的Sybase功能以及遵守ANSI標準(即使唯一約束不符合標準的100%,因爲它們只允許一個NULL值 - a另一方面,唯一索引可以通過在SQL Server 2008和更高版本上添加WHERE子句(WHERE col IS NOT NULL)來解決此問題。

+0

不確定它是否只是區分信息,但是'sys.indexes'有'is_unique_constraint'列來判斷索引是否被定義爲約束而不是唯一索引。 – 2017-07-20 15:31:40

+1

@Andre Yep,這是元數據中的一列,以便*用戶*可以判斷它最初是否被聲明爲約束。這並沒有告訴你有關意圖的任何事情,索引本身的物理實現以及唯一性實施都是一樣的。 – 2017-07-20 18:34:25

10

還有一點要提的是,如果你創建索引,你可以指定包含的列,這可以幫助你的sql代碼更快地工作,如果有country_name的搜索。

​​

SQL服務器將在索引本身中存儲「foo_other_column」。在唯一約束的情況下,它將首先查找'test'的索引,然後搜索foo表中的行,並且僅在那裏將採用「foo_other_column」。