Sql 索引以强制位列中每个表的单个真值
我有一个包含IsDefault列的表:Sql 索引以强制位列中每个表的单个真值,sql,sql-server,tsql,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。我想在数据库级别强制执行此规则 目前,我通过添加一个新的计算列并在其上放置一个唯一的非聚集索引来实现这一点: CREATE TAB
CREATE TABLE CustomerType
(
ID int IDENTITY(1,1) NOT NULL,
Name nvarchar(50) NOT NULL,
IsDefault bit NOT NULL
)
IsDefault值自然应该是TRUE
,对于一行,所有其他行都应该是FALSE
。我想在数据库级别强制执行此规则
目前,我通过添加一个新的计算列并在其上放置一个唯一的非聚集索引来实现这一点:
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
)
这很好,但有一点代码味道,因为额外的列不包含相关数据,只用于强制执行唯一索引
是否有其他方法可以强制执行相同的行为?不幸的是,SQL Server不提供基于函数的索引,这正是您需要的。所以你的方法是最好的 如果附加列太烦人,则使用表上的视图隐藏该列
如果这仍然困扰您,请切换到Oracle;-) 对于SQL Server 2008或更高版本,请使用: 对于旧版本,您使用“穷人过滤索引”,即:
你有没有试过在Oracle论坛上找到答案?我宁愿使用基于纸张的数据库,也不愿接近Oracle,唯一的原因是,试图从SQL Server获得任何帮助都是很糟糕的,因为SQL Server只有5年的筛选索引。对于这个问题,过滤索引可以用索引视图来模拟,这些视图至少在2000年版本的产品中就已经存在了。哇,我不知道过滤索引。看起来是个很棒的功能。
CREATE UNIQUE INDEX IX_Default on CustomerType (IsDefault) WHERE IsDefault = 1
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)