用于在位列中为每个表强制执行单个TRUE值的索引

时间:2014-01-17 09:34:41

标签: sql sql-server tsql

我的表包含IsDefault列:

CREATE TABLE CustomerType
(
    ID int IDENTITY(1,1) NOT NULL,
    Name nvarchar(50) NOT NULL,
    IsDefault bit NOT NULL
)

IsDefault值当然应仅为TRUE一行,所有其他行应为FALSE。我想在数据库级别强制执行此规则。

目前我通过添加一个新的计算列并在其上放置一个独特的NONCLUSTERED INDEX来实现这一目标:

CREATE TABLE CustomerType
(
    ID int IDENTITY(1,1) NOT NULL,
    Name nvarchar(50) NULL,
    IsDefault bit NOT NULL
    IsDefaultConstraint AS (CASE WHEN IsDefault = 1 THEN 1 ELSE -ID END),
)

CREATE UNIQUE NONCLUSTERED INDEX UQ_CustomerType_IsDefault ON CustomerType
(
    IsDefaultConstraint ASC
)

这很好用,但它有一些代码味道,因为额外的列不包含相关数据,仅用于强制执行唯一索引。

是否有其他方法可以强制执行相同的行为?

2 个答案:

答案 0 :(得分:3)

对于SQL Server 2008或更高版本,请使用filtered index

CREATE UNIQUE INDEX IX_Default on CustomerType (IsDefault) WHERE IsDefault = 1

对于旧版本,您使用“穷人的过滤索引”,indexed view

CREATE VIEW dbo.DRI_CustomerType_Default
WITH SCHEMABINDING
AS
   SELECT IsDefault FROM dbo.CustomerType WHERE IsDefault = 1
GO
CREATE UNIQUE CLUSTERED INDEX IX_Default on DRI_CustomerType_Default (IsDefault)

答案 1 :(得分:0)

不幸的是,SQL-Server不提供基于功能的索引,这正是您要寻找的。所以你的方法是最好的。

如果附加列太烦人,则使用隐藏该列的表上的视图。

如果这仍然让你讨厌,请切换到Oracle; - )