实现唯一约束的正确方法,允许SQL Server中的多个NULL值

时间:2011-05-22 13:57:11

标签: sql-server tsql sql-server-2008


我需要表中的1列来保存唯一的非空值或NULL。 TSQL UNIQUE约束将2 NULL s视为相等,因此我无法使列唯一 处理这个问题的正确方法是什么? 经过一番研究,我找到了两种看似正确的方法,但我无法确定哪种方法更好 第一个不适用于所有情况:

CREATE TABLE test (id INT NOT NULL IDENTITY(1,1) PRIMARY KEY, 
   null_or_unique_id INT, unique_key AS  
(CASE WHEN [null_or_unique_id] IS NULL THEN -(1)*[id] 
 ELSE [null_or_unique_id] END), UNIQUE(unique_key ));

它有效,但要求所有允许的null_or_unique_id值为非负值(在我的情况下可以) 第二个:

 CREATE VIEW test_view WITH SCHEMABINDING AS
 SELECT [null_or_unique_id] FROM dbo.test WHERE [null_or_unique_id] IS NOT NULL;
 GO
 CREATE UNIQUE CLUSTERED INDEX byNullOrUniqueId 
 ON dbo.test_view([null_or_unique_id]);

当然,也可以使用触发器实现所需的功能,但我认为触发器解决方案会产生比上面提到的更多的开销。

此类案件的最佳做法是什么? 谢谢你的回答。

3 个答案:

答案 0 :(得分:9)

4种方式:

  • Filtered index(SQL Server 2008)< - 根据您的代码推荐
  • 触发(提及)
  • 索引视图(在您的问题中)
  • 具有计算列的唯一约束/索引(在您的问题中)

答案 1 :(得分:2)

SQL 2008允许您定义过滤的索引 - 本质上是一个带有WHERE子句的索引 - 请参阅Phil Haselden的this question以及MSDN链接的示例。

答案 2 :(得分:2)

将其标准化。将列与当前表的主键一起移动到新表。使列唯一,而不是在新表中为空。可空的独特约束没有逻辑意义,很少或没有实际用途。