F.19. intarray
Модуль intarray
предоставляет ряд полезных функций и операторов для работы с массивами целых чисел без NULL. Также он поддерживает поиск по индексу для некоторых из этих операторов.
Все эти операции выдают ошибку, если в передаваемом массиве оказываются значения NULL.
Многие из этих операций имеют смысл только с одномерными массивами. Хотя им можно передать входной массив и большей размерности, значения будут считываться из него как из линейного массива в порядке хранения.
F.19.1. Функции и операторы intarray
Реализованные в модуле intarray
функции перечислены в Таблице F.11, а операторы — в Таблице F.12.
Таблица F.11. Функции intarray
Таблица F.12. Операторы intarray
Оператор | Возвращает | Описание |
---|---|---|
int[] && int[] | boolean | пересекается с — true , если массивы имеют минимум один общий элемент |
int[] @> int[] | boolean | включает — true , если левый массив содержит правый массив |
int[] <@ int[] | boolean | включается в — true , если левый массив содержится в правом массиве |
# int[] | int | число элементов в массиве |
int[] # int | int | индекс элемента (делает то же, что и функция idx ) |
int[] + int | int[] | вставляет элемент в массив (добавляет его в конец массива) |
int[] + int[] | int[] | соединяет массивы (правый массив добавляется в конец левого) |
int[] - int | int[] | удаляет из массива записи, равные правому аргументу |
int[] - int[] | int[] | удаляет из левого массива элементы правого массива |
int[] | int | int[] | объединение аргументов |
int[] | int[] | int[] | объединение массивов |
int[] & int[] | int[] | пересечение массивов |
int[] @@ query_int | boolean | true , если массив удовлетворяет запросу (см. ниже) |
query_int ~~ int[] | boolean | true , если запросу удовлетворяет массив (коммутирующий оператор к @@ ) |
(До версии PostgreSQL 8.2 операторы включения @>
и <@
обозначались соответственно как @
и ~
. Эти имена по-прежнему действуют, но считаются устаревшими и в конце концов будут упразднены. Заметьте, что старые имена произошли из соглашения, которому раньше следовали ключевые геометрические типы данных!)
Операторы &&
, @>
и <@
равнозначны встроенным операторам Postgres Pro с теми же именами, за исключением того, что они работают только с целочисленными массивами, не содержащими NULL, тогда как встроенные операторы работают с массивами любых типов. Благодаря этому ограничению, в большинстве случаев они работают быстрее, чем встроенные операторы.
Операторы @@
и ~~
проверяют, удовлетворяет ли массив запросу, представляемому в виде значения специализированного типа данных query_int
. Запрос содержит целочисленные значения, сравниваемые с элементами массива, возможно с использованием операторов &
(AND), |
(OR) и !
(NOT). При необходимости могут использоваться скобки. Например, запросу 1&(2|3)
удовлетворяют запросы, которые содержат 1 и также содержат 2 или 3.
F.19.2. Поддержка индексов
Модуль intarray
поддерживает индексы для операторов &&
, @>
, <@
и @@
, а также обычную проверку равенства массивов.
Модуль предоставляет два класса операторов GiST: gist__int_ops
(используется по умолчанию), подходящий для маленьких и средних по размеру наборов данных, и gist__intbig_ops
, применяющий сигнатуру большего размера и подходящий для индексации больших наборов данных (то есть столбцов, содержащих много различных значений массива). В этой реализации используется структура данных RD-дерева со встроенным сжатием с потерями.
Есть также нестандартный класс операторов GIN, gin__int_ops
, поддерживающий те же операторы.
Выбор между индексами GiST и GIN зависит от относительных характеристик производительности GiST и GIN, которые здесь не рассматриваются. Как правило, индекс GIN быстрее индекса GiST при поиске, но строится или обновляется он медленнее; поэтому GIN лучше подходит для статических, а GiST для часто изменяемых данных.
F.19.3. Пример
-- сообщение может относиться к одной или нескольким «секциям»
CREATE TABLE message (mid INT PRIMARY KEY, sections INT[], ...);
-- создать специализированный индекс
CREATE INDEX message_rdtree_idx ON message USING GIST (sections gist__int_ops);
-- вывести сообщения из секций 1 или 2 — оператор пересечения
SELECT message.mid FROM message WHERE message.sections && '{1,2}';
-- вывести сообщения из секций 1 и 2 — оператор включения
SELECT message.mid FROM message WHERE message.sections @> '{1,2}';
-- тот же результат, но с оператором запроса
SELECT message.mid FROM message WHERE message.sections @@ '1&2'::query_int;
F.19.4. Тестирование производительности
В каталоге исходного кода contrib/intarray/bench
содержится набор тестов производительности. Чтобы запустить эти тесты, выполните:
cd .../bench createdb TEST psql TEST < ../_int.sql ./create_test.pl | psql TEST ./bench.pl
Скрипт bench.pl
принимает несколько аргументов, о которых можно узнать, запустив его без аргументов.
F.19.5. Авторы
Разработку осуществили Фёдор Сигаев (<teodor@sigaev.ru>
) и Олег Бартунов (<oleg@sai.msu.su>
). Дополнительные сведения можно найти на странице http://www.sai.msu.su/~megera/postgres/gist/. Андрей Октябрьский проделал отличную работу, добавив новые функции и операторы.