在 SQL Server 中我可以做到这一点
CREATE UNIQUE INDEX [IX_MyTable_Reference]
ON [dbo].[MyTable] ([Reference])
WHERE [Expired] = 0
Firebird 中有类似的吗?
Firebird 4.0 及更早版本不幸的是没有。 Firebird 5.0 确实有条件(或部分)索引,另请参阅 Firebird 支持过滤索引吗? 和 部分索引(不分区)[CORE3384] #3750 和 Firebird 5.0 发行说明)。
我可以想到两种可能的选择:
使用唯一的计算索引,当
Reference
为 0 时存储 Expired
,否则存储 null
:
create unique index "IX_MyTable_Reference"
on "MyTable"
computed by (iif("Expired" = 0, "Reference", null));
此索引将强制唯一性,但只能在字面上使用
iif("Expired" = 0, "Reference", null) = <somevalue>
的查询中用作索引本身,这使得与部分索引相比,用作索引更加复杂且不太直观(您将在其中使用可以使用"Expired" = 0 and "Reference" = <somevalue>
)。
使用填充单独表的触发器,该表可以通过唯一约束(或索引)强制执行唯一性,以及在删除时删除记录(或使用级联外键约束)或
Expired
值更改的触发器。
此解决方案没有提供查询时拥有索引的好处(除非显式加入附加表)。
考虑到这个解决方案的复杂性,我将其作为练习留给读者。
其他潜在的替代方案,例如使用检查约束或触发器来检查当前表的内容,不会阻止并发事务插入重复项,也不会获得部分索引的好处。