SQL 有条件的服务器索引
SQL Server index with condition
我有 table Range
列
Start (date), RangeTypeId (integer), ChannelId (integer), IsActive (bit)
我有这个索引:
CREATE UNIQUE NONCLUSTERED INDEX [IX_Range_Unique]
ON [dbo].[Range] ([Start] ASC, [RangeTypeId] ASC, [ChannelId] ASC, [IsActive] ASC)
我希望我的索引仅在具有 IsActive = 1
的 2 行的情况下防止插入或更新。所以我想要索引或某种触发器,允许多个 Ranges
具有 IsActive = 0
和相同的开始日期、频道 ID 和类型,但只有一个具有 IsActive = 1
和相同的开始日期,频道 ID 和类型。
有效数据库示例 table 状态:
Start | RangeTypeId | ChannelId | IsActive
------------------------------------------
23:00 5 1 0
23:00 5 1 0
23:00 5 1 0
23:00 5 1 1
无效:
Start | RangeTypeId | ChannelId | IsActive
------------------------------------------
23:00 5 1 0
23:00 5 1 0
23:00 5 1 1
23:00 5 1 1
可能吗?
您可以像这样创建独一无二的 filtered index:
CREATE UNIQUE NONCLUSTERED INDEX [uIXf_Range_Unique] ON [dbo].[Range]
(
[Start] ASC,
[RangeTypeId] ASC,
[ChannelId] ASC,
[IsActive] ASC
)
where IsActive = 1
rextester 演示:http://rextester.com/LBI81243
create table range ([Start] varchar(5), [RangeTypeId] int, [ChannelId] int, [IsActive] int) ;
insert into range ([Start], [RangeTypeId], [ChannelId], [IsActive]) values
('23:00', 5, 1, 0),
('23:00', 5, 1, 0),
('23:00', 5, 1, 0),
('23:00', 5, 1, 1)
;
CREATE UNIQUE NONCLUSTERED INDEX [uIXf_Range_Unique] ON [dbo].[Range]
(
[Start] ASC,
[RangeTypeId] ASC,
[ChannelId] ASC,
[IsActive] ASC
)
where IsActive = 1
go
/* throws an error error due to duplicate key */
insert into range ([Start], [RangeTypeId], [ChannelId], [IsActive]) values
('23:00', 5, 1, 1)
恕我直言,UNIQUE FILTERED INDEX
有一大缺点。
索引的主要目的是加速select查询。
所以上面的索引可能在大多数 select 查询中都没有使用,在这种情况下我们经常更改索引 .
所以索引的主要目的是 defeated.In 在这种情况下我们删除索引并在其他 column/columns 上创建索引 column/columns。
Filtered index
的想法也不同于使用 here.Purpose 过滤索引是,如果在大量数据中,我们非常频繁地查询某个值,那么我们会使用该值在该列上创建过滤索引喜欢 above.Its 目的不是提供唯一性。
假设 DBA 不知道此计划并且 DBA 决定删除此索引,那么您可能会开始获取重复记录。
因此,在这种情况下检查重复项的最佳方法是通过代码进行检查。
if not exists (select id from mytable where [Start]=@Start and [RangeTypeId]=@RangeTypeId
and [ChannelId]=@ChannelId and [IsActive]=1)
BEGIN
print 'insert'
END
如果 insert/update 可以从多个地方发生,那么使用触发器是明智的。
我有 table Range
列
Start (date), RangeTypeId (integer), ChannelId (integer), IsActive (bit)
我有这个索引:
CREATE UNIQUE NONCLUSTERED INDEX [IX_Range_Unique]
ON [dbo].[Range] ([Start] ASC, [RangeTypeId] ASC, [ChannelId] ASC, [IsActive] ASC)
我希望我的索引仅在具有 IsActive = 1
的 2 行的情况下防止插入或更新。所以我想要索引或某种触发器,允许多个 Ranges
具有 IsActive = 0
和相同的开始日期、频道 ID 和类型,但只有一个具有 IsActive = 1
和相同的开始日期,频道 ID 和类型。
有效数据库示例 table 状态:
Start | RangeTypeId | ChannelId | IsActive
------------------------------------------
23:00 5 1 0
23:00 5 1 0
23:00 5 1 0
23:00 5 1 1
无效:
Start | RangeTypeId | ChannelId | IsActive
------------------------------------------
23:00 5 1 0
23:00 5 1 0
23:00 5 1 1
23:00 5 1 1
可能吗?
您可以像这样创建独一无二的 filtered index:
CREATE UNIQUE NONCLUSTERED INDEX [uIXf_Range_Unique] ON [dbo].[Range]
(
[Start] ASC,
[RangeTypeId] ASC,
[ChannelId] ASC,
[IsActive] ASC
)
where IsActive = 1
rextester 演示:http://rextester.com/LBI81243
create table range ([Start] varchar(5), [RangeTypeId] int, [ChannelId] int, [IsActive] int) ;
insert into range ([Start], [RangeTypeId], [ChannelId], [IsActive]) values
('23:00', 5, 1, 0),
('23:00', 5, 1, 0),
('23:00', 5, 1, 0),
('23:00', 5, 1, 1)
;
CREATE UNIQUE NONCLUSTERED INDEX [uIXf_Range_Unique] ON [dbo].[Range]
(
[Start] ASC,
[RangeTypeId] ASC,
[ChannelId] ASC,
[IsActive] ASC
)
where IsActive = 1
go
/* throws an error error due to duplicate key */
insert into range ([Start], [RangeTypeId], [ChannelId], [IsActive]) values
('23:00', 5, 1, 1)
恕我直言,UNIQUE FILTERED INDEX
有一大缺点。
索引的主要目的是加速select查询。 所以上面的索引可能在大多数 select 查询中都没有使用,在这种情况下我们经常更改索引 .
所以索引的主要目的是 defeated.In 在这种情况下我们删除索引并在其他 column/columns 上创建索引 column/columns。
Filtered index
的想法也不同于使用 here.Purpose 过滤索引是,如果在大量数据中,我们非常频繁地查询某个值,那么我们会使用该值在该列上创建过滤索引喜欢 above.Its 目的不是提供唯一性。
假设 DBA 不知道此计划并且 DBA 决定删除此索引,那么您可能会开始获取重复记录。
因此,在这种情况下检查重复项的最佳方法是通过代码进行检查。
if not exists (select id from mytable where [Start]=@Start and [RangeTypeId]=@RangeTypeId
and [ChannelId]=@ChannelId and [IsActive]=1)
BEGIN
print 'insert'
END
如果 insert/update 可以从多个地方发生,那么使用触发器是明智的。