PostgreSQL exclusion constraint: запретить пересечение дат
Exclusion constraint в PostgreSQL запрещает пары строк, для которых одновременно выполняется заданное сравнение. Для расписания бронирований это позволяет отклонить пересекающиеся интервалы одной комнаты прямо на уровне базы, в том числе при конкурентных запросах. Пример использует диапазон дат daterange и расширение btree_gist.
Запретить две брони на один номер и период
Установите расширение в нужной базе с ролью, которой это разрешено, затем добавьте constraint к таблице:
CREATE EXTENSION IF NOT EXISTS btree_gist;
CREATE TABLE room_booking (
room_id integer NOT NULL,
stay daterange NOT NULL,
EXCLUDE USING gist (
room_id WITH =,
stay WITH &&
)
);Оператор && проверяет пересечение диапазонов, а room_id WITH = ограничивает проверку бронями той же комнаты. Например, диапазон daterange('2026-11-10', '2026-11-12', '[)') включает 10 и 11 ноября, но исключает 12-е. Поэтому следующая бронь может начаться 12 ноября без пересечения.
При конфликте INSERT или UPDATE завершится ошибкой нарушения exclusion constraint. Если таблица уже содержит пересекающиеся брони, добавление ограничения не пройдёт, пока конфликтующие строки не будут исправлены. Установка btree_gist меняет схему базы и может требовать повышенных прав; согласуйте её перед применением.
Официальная справка: Exclusion Constraints и btree_gist.