Уникальность Oracle

Мне нужно обеспечить уникальность определенных данных в таблице (~ 10 миллионов строк). Этот пример данных иллюстрирует правило: для code=X номер детали не может повторяться. Для любого другого кода может быть повторяющийся номер детали. например, строка ID 8 не может быть там, но строка ID 6 в порядке. В таблице и части # есть несколько разных кодов, но уникальность требуется только для одного кода = X.

ID      CODE        PART#
1       A           R0P98
2       X           R9P01
3       A           R0P98
4       A           R0P44
5       X           R0P44
6       A           R0P98
7       X           T0P66
8       X           T0P66

Единственный способ, который я вижу, - это создать триггер в таблице и проверить ЧАСТЬ # для кода = X перед вставкой или обновлением. Однако я боюсь, что это решение может замедлить вставки и обновления в этой таблице.

Ценю твою помощь!


person blueolive    schedule 14.09.2020    source источник


Ответы (1)


В Oracle вы можете создать для этого уникальный индекс выражения:

create unique index myidx
    on mytable (case when code = 'X' then part# end);
person GMB    schedule 14.09.2020
comment
Это один из случаев, когда я считаю, что стандарт SQL несовершенен. Ограничения SQL не могут обеспечить соблюдение этого правила. Просто странно использовать индекс для задания ограничения. - person The Impaler; 15.09.2020
comment
@TheImpaler: я считаю, что уникальный индекс является правильным инструментом для этой работы. Oracle, однако, весьма ограничен в этом отношении. Postgres, например, как правильный частичный уникальный индекс, например: create unique index myidx on mytable(part#) where (code = 'X') - person GMB; 15.09.2020
comment
@GMB - спасибо! У меня есть дополнительная проблема с реализацией индекса таким образом. Значение кода не фиксируется на разных коробках. Существует основная таблица кодов, в которой хранятся коды для этого ящика/схемы. Поэтому, если я попробую, как показано ниже, это не сработает. Конечно, я могу динамически создать его, получая это значение кода для каждого блока/схемы, но есть вероятность, что кто-то может обновить код для этого блока/схемы. Однако мастер-код никогда не изменится. создать уникальный индекс myidx в mytable (случай, когда code = (выберите код из master_codes, где master_code = 'PRAM'), затем часть # end); - person blueolive; 15.09.2020
comment
Как добавить в этот индекс еще один столбец, например ID? - person blueolive; 16.09.2020
comment
@blueolive: это будет что-то вроде (case when code = 'X' then part# || '&&' || id end); (при условии, что && — это последовательность символов, которая никогда не появляется в ваших строках) - person GMB; 16.09.2020