Условный уникальный индекс в Firebird - PullRequest
2 голосов
/ 01 августа 2020

На SQL сервере я могу это сделать

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

Есть ли аналог в Firebird?

1 Ответ

1 голос
/ 01 августа 2020

К сожалению, нет. Firebird не имеет условных (или частичных) индексов.

Я могу придумать две возможные альтернативы:

  1. Используйте уникальный вычисляемый индекс, который хранит Reference, когда Expired равно 0 и 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.

    Это решение не дает преимуществ наличие индекса при запросе (кроме, может быть, явного присоединения к дополнительной таблице).

    Учитывая сложность этого решения, я оставляю это в качестве упражнения для читателя. * 1 024 *

Другие возможные альтернативы, такие как использование ограничения проверки или триггера для проверки содержимого текущей таблицы, не помешают параллельным транзакциям вставлять дубликаты, и вы не получите преимуществ от наличия частичного индекса .

...