首页 文章

Unique Constraint列只能包含一个NULL值

提问于
浏览
7

可以在包含NULL的列上创建唯一约束 . 但是,最多只有一行可能在该列中包含NULL .

我不明白为什么会这样,因为根据定义,NULL不等于另一个NULL(因为NULL实际上是一个未知值,一个未知值不等于另一个未知值) .

我的问题:1 . 为什么会这样? 2.这是针对MsSQL的吗?

我有一个预感,因为Unique Constraint可以充当外键的引用字段,并且如果存在多个具有NULL的记录,则FK否则将不知道它引用的引用表中的哪个记录 . 但是,这只是一种预感 .

(是的,我知道UC可以跨多个列,但这不会改变问题;相反,它只会让它复杂化 . )

2 回答

  • 9

    是的,它是"specific"到Microsoft SQL Server(因为其他一些数据库系统有相反的方法,你期望的那个 - 以及ANSI标准中定义的那个,但我相信还有其他数据库系统与SQL Server相同) .

    如果您正在使用支持筛选索引的SQL Server版本,则可以应用以下其中一个:

    CREATE UNIQUE INDEX IX_T ON [Table] ([Column]) WHERE [Column] IS NOT NULL
    

    (但请注意,此索引不能成为FK约束的目标)


    它的“为什么”真正归结为,它就是很久以前实现的(可能是预标准),而现在改变它的那些尴尬局面之一可能会破坏很多现有系统 .

    Re:外键 - 如果不是因为外键列中的 NULL 值导致不检查外键这一事实你会是正确的 - 没有办法(在SQL Server中)使用 NULL 作为实际键 .

  • 5

    是的,鉴于在SQL中其他地方应用于空值的逻辑,这是非常有意义的 - 但是ISO SQL标准根本不是't very consistent about its treatment of nulls either. The behaviour of nullable uniqueness constraints in Standard SQL is not very helpful. Such constraints aren',因为它们允许重复的行 . 例如,约束 UNIQUE(foo,bar) 允许以下行同时存在于表中:

    foo    bar
    ------ ------
    999    NULL
    999    NULL
    

    (!)

    避免可空的唯一性约束 . 将列作为非可空列移动到新表并将唯一性约束放在那里通常很简单 . 通过用空值填充这些列来表示的信息可以(可能)通过根本不填充新表中的那些列来表示 .

相关问题