Firebird 中的条件唯一索引

Conditional unique index in Firebird

在 SQL 服务器中我可以做到这一点

CREATE UNIQUE INDEX [IX_MyTable_Reference]
    ON [dbo].[MyTable] ([Reference])
    WHERE [Expired] = 0

Firebird 中是否有等效项?

不幸的是没有。 Firebird 没有条件(或部分)索引。

我可以想到两种可能的选择:

  1. 使用唯一的计算索引,当 Expired 为 0 时存储 Reference,否则 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>)。

  2. 使用一个触发器来填充一个单独的 table,它可以通过唯一约束(或索引)强制执行唯一性,以及一个在删除时删除记录的触发器(或使用级联外部键约束)或者如果 Expired 值发生变化。

    此解决方案在查询时没有提供索引的好处(除非明确加入额外的 table)。

    鉴于此解决方案的复杂性,我将其作为练习留给 reader。

其他可能的替代方法,例如使用检查约束或触发器来检查当前 table 的内容,不会阻止并发事务插入重复项,您也不会获得部分索引的好处。