Исключить ограничение для многих таблиц? - PullRequest
0 голосов
/ 15 марта 2019

Рассмотрим следующую таблицу:

todos:

 id | floor_start | floor_end
----+-------------+-------------
 1  | 10          | 20
 2  | 20          | 30
 3  | 30          | 40
 4  | 35          | 45

для предотвращения 2 лифтов на одном этаже, с которыми я могу пойти:

EXCLUDE USING gist(int4range(start,end) with &&)

В этом случае 3 будет конфликтовать с 4.

Однако у меня есть таблица присоединения:

occupations:

 todo_id | room_id
---------+----------
 3       | 1
 4       | 2

, поэтому (3) выполняется в room_id = 1 и (4) выполняется в room_id = 2, и они не конфликтуют.

1 & 2 не имеют записи в объединяющей таблице, поэтому все комнаты заняты.

Я понимаю, что exclude будет работать только в рамках текущей таблицы - как я могу справиться сЭто?Стоит ли создавать избыточные столбцы?

Добавление room_id к todos не вариант, потому что это лишь минимальный пример, и в реальном приложении у меня больше 0..N присоединений.

1 Ответ

2 голосов
/ 15 марта 2019

Вы можете написать триггер AFTER INSERT OR UPDATE, который проверяет условие и выдает ошибку, если оно не выполнено.

Но следует помнить, что такие триггеры имеют условие гонки - две одновременные модификации данных не могут видеть каждыйдругие эффекты.Поэтому вы должны либо использовать уровень изоляции SERIALIZABLE, либо заблокировать соответствующие строки в триггере с помощью SELECT ... FOR UPDATE.

...