Firebird 中的条件唯一索引

问题描述 投票:0回答:1

在 SQL Server 中我可以做到这一点

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

Firebird 中有类似的吗?

sql firebird
1个回答
2
投票

Firebird 4.0 及更早版本不幸的是没有。 Firebird 5.0 确实有条件(或部分)索引,另请参阅 Firebird 支持过滤索引吗?部分索引(不分区)[CORE3384] #3750Firebird 5.0 发行说明)。

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

  1. 使用唯一的计算索引,当

    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>
    )。

  2. 使用填充单独表的触发器,该表可以通过唯一约束(或索引)强制执行唯一性,以及在删除时删除记录(或使用级联外键约束)或

    Expired
    值更改的触发器。

    此解决方案没有提供查询时拥有索引的好处(除非显式加入附加表)。

    考虑到这个解决方案的复杂性,我将其作为练习留给读者。

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

© www.soinside.com 2019 - 2024. All rights reserved.