Sql-Server
為什麼一個 UNIQUE 約束只允許一個 NULL?
從技術上講,NULL = NULL 是 False,按照這種邏輯,沒有 NULL 等於任何 NULL,並且所有 NULL 都是不同的。這不應該暗示所有 NULL 都是唯一的,並且唯一索引應該允許任意數量的 NULL 嗎?
為什麼它會這樣工作?因為很久以前,有人在不知道或不在乎標准說什麼的情況下做出了設計決定(畢竟,我們確實有各種奇怪的
NULL
s 行為,並且可以隨意強制不同的行為)。該決定規定,在這種情況下,NULL = NULL
.這不是一個非常明智的決定。他們應該做的是讓預設行為遵守 ANSI 標準,如果他們真的想要這種特殊行為,請通過像
WITH CONSIDER_NULLS_EQUAL
or之類的 DDL 選項來允許它WITH ALLOW_ONLY_ONE_NULL
。當然,事後看來是 20/20。
無論如何,我們現在有一個解決方法,即使它不是最乾淨或最直覺的。
您可以通過創建唯一的過濾索引在 SQL Server 2008 及更高版本中獲得正確的 ANSI 行為。
CREATE UNIQUE INDEX foo ON dbo.bar(key) WHERE key IS NOT NULL;
這允許多個
NULL
值,因為這些行完全被排除在重複檢查之外。作為一個額外的好處,如果允許多個 s ,這最終將是一個比包含整個表的索引更小的索引NULL
(特別是當它不是索引中的唯一列時,它有INCLUDE
列等)。但是,您可能想了解過濾索引的其他一些限制: