Запретить пересекающиеся бронирования в базе
Вопрос
Таблица bookings(room_id int, during tstzrange). Как гарантировать на уровне базы, что одну комнату нельзя забронировать на пересекающееся время?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
UNIQUE (room_id, during)с индексом по диапазону- Триггер с
SELECTна пересечения перед вставкой (Read Committed) EXCLUDE USING gist (room_id WITH =, during WITH &&)правильный ответ- B-tree индекс по
(room_id, lower(during), upper(during))
Разбор
Exclusion-ограничение обобщает уникальность: запрещает две строки, для которых все перечисленные операторы истинны, то есть та же комната и пересекающиеся (&&) интервалы. Оно строится на GiST, а чтобы GiST умел обычное равенство по int, подключают расширение btree_gist. UNIQUE поймает только полностью совпадающие интервалы. Триггер с проверкой через SELECT на Read Committed пропустит гонку: две транзакции одновременно не увидят друг друга и обе вставят. B-tree не умеет проверять пересечение диапазонов.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.