В комментариях к заметке об ограничениях PostgreSQL подписчик напомнил еще и про EXCLUDE ограничения. Давайте разберемся что это такое и посмотрим еще на кое-что 😊.
EXCLUDE (исключающие) ограничения могут нам помощь тогда, когда нам нужно отслеживать какие-то пересекающиеся диапазоны данных. Т.е., например, если у нас есть база данных бронирования номеров отелей, то мы не хотим, чтобы один и тот же номер могли забронировать на одну и ту же дату разные люди. Или если мы занимаемся сдачей машин в аренду, то мы не хотим чтобы одну и туже машину взяли в аренду разные люди в одно и тоже время ну т.д. Справится с такими ситуациями нам и помогут EXCLUDE ограничения.
Для установки таких ограничений используется оператор EXCLUDE. Этот оператор часто используется с индексом типа GiST или SP-GiST, чтобы обеспечить эффективность выполнения запросов, хотя может применяться и вместе с обычным B-Tree индексом.
Пример. Стандартным примером применения таких ограничений может быть пересечение временных интервалов, например сеансов в кинозале. Допустим у нас есть вот такая таблица:
CREATE TABLE events (
id serial primary key,
event_time tstzrange,
CONSTRAINT no_time_overlap EXCLUDE USING gist (event_time WITH && )
);
Здесь:
event_time - время начала события (сеанса);
no_time_overlap - название нашего ограничения;
EXCLUDE USING gist - установка исключающего ограничения с использованием индекса Gist;
event_time WITH && - эта конструкция как раз и будет проверять при вставке или обновлении строки в таблицу, не пересекаются ли ее значения с уже имеющимися. Здесь && - оператор, который и проверяет пересечение диапазонов, т.е. возвращает истину если они пересекаются и ложь, если нет.
DEFERRABLE (отложенные) ограничения.
Фактически это не отдельный вид ограничений, а возможность отложить их проверку во время выполнения транзакции. Ограничения будут проверены не сразу, а в момент завершения транзакции (COMMIT). Ограничения CHECK и NOT NULL нельзя отложить.
В PostgreSQL уровень всех ограничений по умолчанию — NOT DEFERRABLE. Мы можем сделать ограничение отложенным сразу при его создании с помощью команды DEFERRABLE INITIALLY IMMEDIATE, или же временно сделать отложенным уже существующее ограничение в таблице с помощью вот такой команды:
SET CONSTRAINTS constraint_name DEFERRED;
Когда отложенные ограничения могут быть полезны? В основном в очень больших операциях по вставке данных в таблицу, когда мы не хотим, чтобы ограничения проверялись для каждой строчки отдельно, а проверились все и сразу в конце транзакции, чтобы ускорить вставку, например, или еще каких-то операциях, при которых проверка ограничений сразу может мешать. Но злоупотреблять отложенными ограничениями не нужно! Потому что они могут влиять на работу планировщика запросов PostgreSQL, затрудняя проверку данных в таблице.
Как видите, в PostgreSQL есть очень интересные фишки, которые могут пригодиться в той или иной ситуации.
На сегодня все! До связи!
#pgbase