过滤索引表达式不适用于 Bit

Filtered Index expression does not work on Bit

我想对 IsDefaultLanguage 列的特定值进行 bool 约束:

Id...ISO639_ISO3166...ApplicationId...IsDefaultLanguage
1....de-de............1...............1
2....fr-fr............1...............1

第二个数据行插入应该导致唯一错误,因为对于应用程序,IsDefaultLanguage 应该只允许一个表示 True (1)。 此外,一种语言是否应该只适用于一种应用程序。

过滤器索引在我这边不起作用(Sql Server 2014)

我做错了什么?

TABLE

CREATE TABLE [dbo].[Languages](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ISO639_ISO3166] [char](5) NOT NULL,
    [ApplicationId] [int] NOT NULL,
    [IsDefaultLanguage] [bit] NOT NULL,
 CONSTRAINT [PK_dbo.Languages] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Languages]  WITH CHECK ADD  CONSTRAINT [FK_dbo.Languages_dbo.Applications_ApplicationId] FOREIGN KEY([ApplicationId])
REFERENCES [dbo].[Applications] ([Id])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[Languages] CHECK CONSTRAINT [FK_dbo.Languages_dbo.Applications_ApplicationId]
GO

索引

CREATE UNIQUE NONCLUSTERED INDEX [IX_IsoCodeApplicationId] ON [dbo].[Languages]
(
    [ISO639_ISO3166] ASC,
    [ApplicationId] ASC,
    [IsDefaultLanguage] ASC
)
WHERE ([IsDefaultLanguage]=(1))
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO

The second datarow insertion should result in a unique error because IsDefaultLanguage should only be allowed ONE for True (1) for an application. Also should a language be available only ONE for an application.

以上我不是很清楚。这就是我认为你想说的:

  • IsDefaultLanguage 每个 ApplicationId.
  • 只能有一次值 1
  • ISO639_ISO3166 的值在每个 ApplicationId
  • 中必须是唯一的

如果是这种情况,请将您的索引拆分为 2 个单独的索引,以满足您的 2 个不同要求:

CREATE UNIQUE NONCLUSTERED INDEX [IX_IsoCodeApplicationId] ON [dbo].[Languages]
(
    [ISO639_ISO3166] ASC,
    [ApplicationId] ASC
)

CREATE UNIQUE NONCLUSTERED INDEX [IX_DefaultLanguageApplicationId] ON [dbo].[Languages]
(
    [IsDefaultLanguage] ASC,
    [ApplicationId] ASC,
)
WHERE ([IsDefaultLanguage]=(1))

您的索引定义不正确,无法满足您的要求。让我们换个角度来看。您预计以下查询会 return 0 行:

select [ApplicationID], count(*)
from [dbo].[Languages]
where [IsDefaultLanguage] = 1
group by [ApplicationID]
having count(*) > 1

也就是说,对于每个 ApplicationID,只有一行的值为 IsDefaultLanguage = 1。因此,您的索引应该是:

CREATE UNIQUE NONCLUSTERED INDEX [IX_IsoCodeApplicationId] 
ON [dbo].[Languages]
(
    [ApplicationId] ASC
)
WHERE ([IsDefaultLanguage]=(1))

完成与查询的类比,索引中的每个 ApplicationID 将(读取:可以)只有一行(因为它是唯一索引)。