btree_gist. Показательные классы операторов GIST
В исходном дистрибутиве установлено по умолчанию: нет.
Связанные компоненты: отсутствуют
Схема размещения:
ext
Модуль предоставляет показательные классы операторов GiST
, которые реализуют поведение, подобное поведению обычных классов B-дерева (b-tree
), для следующих типов данных:
int2
;int4
;int8
;float4
;float8
;timestamp with time zone
;timestamp without time zone
;time with time zone
;time without time zone
;date
;interval
;oid
;money
;char
;varchar
;text
;bytea
;bit
;varbit
;macaddr
;macaddr8
;inet
;cidr
;uuid
;- все типы
enum
.
Описание
Работа с индексами GiST
GiST (Generalized search tree) - сбалансированное дерево поиска, схожее с b-tree
. Однако, в отличие от b-tree
, которое поддерживает только операторы <, >, =, GiST дает возможность использовать самые разнообразные операторы, например (<@, &&). При этом смысл операторов определяется типом данных, для которого он применяется. Таким образом, GiST предоставляет расширяемый интерфейс для хранения и поиска по любым типам данных с использованием операций, специфичных именно для этого типа.
Рассмотрим в качестве примера задачу поиска по временным интервалам (тип tsrange
). Допустим, сдается дом, и есть таблица, хранящая интервалы бронирования:
CREATE TABLE reservations(during tsrange);
INSERT INTO reservations(during) VALUES
('[2016-12-30, 2017-01-09)'),
('[2017-02-23, 2017-02-27)'),
('[2017-04-29, 2017-05-02)');
CREATE INDEX ON reservations USING gist(during);
На вход подается интервал [2017-01-01, 2017-04-01)
, нужно найти все интервалы, пересекающиеся с ним:
SELECT * FROM reservations WHERE during && '[2017-01-01, 2017-04-01)';
Для типа tsrange
оператор &&
означает «пересечение».
Индекс GiST может применяться для поддержки ограничений исключения (exclude
).
Добавим ограничение, которое запретит бронирование, если нужные даты уже заняты:
ALTER TABLE reservations ADD exclude USING gist(during WITH &&);
Попытка добавить интервал, уже имеющийся в таблице, завершится ошибкой:
INSERT INTO reservations(during) VALUES ('[2017-01-01, 2017-04-01)');
Описание расширения btree_gist
Допустим, нужно сдавать несколько домов. В таблицу reservation
добавьте номер дома:
ALTER TABLE reservations ADD house_no INTEGER DEFAULT 1;
Необходимо изменить ограничение исключения так, чтобы учитывать и номер дома. Однако GiST не поддерживает операцию равенства для целых чисел.
В этом случае используйте расширение btree_gist
, которое добавляет GiST-поддержку операций, характерных для B-деревьев (<, >, =):
CREATE extension btree_gist;
ALTER TABLE reservations DROP CONSTRAINT reservations_during_excl;
ALTER TABLE reservations ADD exclude USING gist(during WITH &&, house_no WITH =);
Убедитесь, что можно забронировать на те же даты не только первый дом, но и второй
INSERT INTO reservations(during, house_no) VALUES ('[2017-01-01, 2017-04-01)', 2);
Учитывайте, что при необходимости простого сравнения (<, >, =), более предпочтительно использовать простые b-tree
индексы, так как они работают быстрее.
btree_gin
имеет смысл использовать только в том случае, если условие дополнительно содержит операцию над сложными объектами, как в примере выше.
В дополнение к основным операциям b-tree
, btree_gin
добавляет оператор <> (не равно), который удобно использовать в ограничениях исключения (exclude constraints
). Например:
CREATE TABLE zoo ( cage INTEGER, animal TEXT, EXCLUDE USING gist (cage WITH =, animal WITH <>) );
Доработка
Не проводилась.
Ограничения
Существуют следующие ограничения:
- классы операторов
GiST
не будут работать быстрее аналогичных стандартных методов индекса-B-tree
; - нет возможности ограничивать уникальность.
Установка
Расширение входит в стандартную поставку Pangolin. Для использования необходимо выполнить:
CREATE EXTENSION btree_gist SCHEMA ext;
Настройка
Не требуется.
Использование модуля
Использование btree_gist
вместо btree
:
CREATE TABLE test (a int4);
-- создать индекс
CREATE INDEX testidx ON test USING GIST (a);
-- запрос
SELECT * FROM test WHERE a < 10;
-- поиск ближайших соседей: найти десять записей, ближайших к "42"
SELECT *, a <-> 42 AS dist FROM test ORDER BY a <-> 42 LIMIT 10;
Ссылки на документацию разработчика
Дополнительно поставляемый модуль btree_gist: https://www.postgresql.org/docs/15/btree-gist.html.