2013-07-05 56 views
6

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

我不明白为什么会出现这种情况,因为根据定义,NULL不等于另一个NULL(因为NULL实际上是一个未知值,一个未知值不等于另一个未知值)。

我的问题: 1.这是为什么? 2.这是特定于MsSQL吗?

我有一种预感,那是因为唯一约束可以充当外键的引用字段,否则FK将不知道引用表中的哪个记录,如果多于一条记录与NULL存在。但是,这只是一种预感。

(是的,我明白,UCS可以跨越多个列,但是这并没有改变的问题,相反,它只是有点复杂了。)

+0

您可以粘贴CREATE TABLE语句。难道是你设置值'NULL'作为字符串而不是真正的NULL –

+0

公平的评论,但是,不,它不是一个字符串;它是一个整数字段。尝试输入或将现有的整数值更改为NULL会导致“违反UNIQUE KEY约束...不能在对象中插入重复键...” –

回答

7

是的,这是“具体”到Microsoft SQL Server( 其他数据库系统有相反的方法,这是你期望的 - 也是ANSI标准中定义的那种,但我相信还有其他数据库系统与SQL Server相同)。

如果你在一个版本,支持过滤索引SQL服务器的工作,你可以申请其中的一个:

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

(但请注意,这个指标不能是一个FK约束的目标)


的呢“为什么”实际上只是归结为,这就是它是多久以前(可能是预标准)实现,它的那些尴尬的情况下改变它现在可能突破很多现有的一个系统。

回复:外键 - 如果不是外键列中的NULL值导致外键不被检查的事实 - 你应该是正确的 - 没有办法(在SQL Server中)使用NULL作为一个实际的关键。

+0

这有助于我理解,所以谢谢。在这种情况下,我真的想要了解情况而不是“解决问题”。而且,DOH,符合我的FK假设;我应该记住允许的不允许NULL。 –

+0

FOREIGN KEY约束肯定*不允许在标准SQL和SQL Server中使用空值。可空的FK约束允许在引用父表中是否有任何内容被引用。 – sqlvogel

+0

@sqlvogel - 我的意思是在引用表中不会检查引用表中的NULL值。 'NULL'不能是一个关键值。 –

3

是的,这是SQL Server功能(和一些其他DBMS的功能),违反了ISO SQL标准。考虑到SQL在其他地方的空值应用逻辑可能没有多大意义 - 但是随后ISO SQL标准对它的空值处理也不是很一致。标准SQL中的可为空的唯一性约束的行为不是很有帮助。这样的约束根本不一定是“唯一的”,因为它们允许重复的行。例如,UNIQUE(foo,bar)允许以下行的约束在一个表中同时存在:(!)

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

避免为空的唯一性约束。将列移动到新表格通常很简单,如不可为空的列,并将唯一性约束放在那里。通过用空值填充这些列来表示的信息可能(大概)可以通过简单地不填充新表中的那些列来表示。