Sql-Server

為什麼一個 UNIQUE 約束只允許一個 NULL?

  • January 15, 2018

從技術上講,NULL = NULL 是 False,按照這種邏輯,沒有 NULL 等於任何 NULL,並且所有 NULL 都是不同的。這不應該暗示所有 NULL 都是唯一的,並且唯一索引應該允許任意數量的 NULL 嗎?

為什麼它會這樣工作?因為很久以前,有人在不知道或不在乎標准說什麼的情況下做出了設計決定(畢竟,我們確實有各種奇怪的NULLs 行為,並且可以隨意強制不同的行為)。該決定規定,在這種情況下,NULL = NULL.

這不是一個非常明智的決定。他們應該做的是讓預設行為遵守 ANSI 標準,如果他們真的想要這種特殊行為,請通過像WITH CONSIDER_NULLS_EQUALor之類的 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列等)。但是,您可能想了解過濾索引的其他一些限制:

引用自:https://dba.stackexchange.com/questions/80514