У меня есть таблица меток, которые отображаются в ранжированном порядке. Чтобы гарантировать, что никакие две строки не могут иметь одинаковый ранг, их значения уникальны:
create table label (
id_label serial not null,
rank integer not null,
title text not null,
constraint pri primary key (id_label),
constraint unq unique (rank)
)
Не имеет значения, PostgreSQL или MySQL, они демонстрируют одинаковое поведение. Запрос может выглядеть так: выберите заголовок из порядка ярлыков по рангу
. Предположим, что таблица содержит:
id_label rank title
1 10 Cow
2 20 Apple
3 45 Horse
4 60 Beer
Теперь предположим, что я хочу переупорядочить две метки, например, поставить Apple выше коровы. Самый простой способ - поменять местами их значения ранга:
update label
set rank = case when rank = 20 then 10 else 20 end
where id_label in (1,2)
Нет. Ни:
update label
set rank = case when rank = 20 then rank - 10 else rank + 10 end
where id_label in (1,2)
Ни даже:
update label
set rank = 30 - rank
where id_label in (1,2)
Каждый раз уникальное ограничение срабатывает при обновлении первой строки и прерывает операцию. Если бы я мог отложить проверку до конца заявления, я был бы в порядке. Это происходит как в PostgreSQL, так и в MySQL.
Безопасный для ACID обходной путь:
Это просто невыразимо уродливо. Хуже того, нужно отбросить ограничение, обновить, а затем воссоздать ограничение. Предоставление таких привилегий оперативной роли вызывает проблемы. Итак, мой вопрос: есть ли простой метод, который я упустил из виду, который решает эту проблему, или я - СОЛНЕЧНЫЙ?