F.20. intarray — работа с массивами целых чисел #
Модуль intarray
предоставляет ряд полезных функций и операторов для работы с массивами целых чисел без NULL. Также он поддерживает поиск по индексу для некоторых из этих операторов.
Все эти операции выдают ошибку, если в передаваемом массиве оказываются значения NULL.
Многие из этих операций имеют смысл только с одномерными массивами. Хотя им можно передать входной массив и большей размерности, значения будут считываться из него как из линейного массива в порядке хранения.
Данный модуль считается «доверенным», то есть его могут устанавливать обычные пользователи, имеющие право CREATE
в текущей базе данных.
F.20.1. Функции и операторы intarray
#
Реализованные в модуле intarray
функции перечислены в Таблице F.9, а операторы — в Таблице F.10.
Таблица F.9. Функции intarray
Таблица F.10. Операторы intarray
Оператор Описание |
---|
Массивы пересекаются (у них есть минимум один общий элемент)? |
Левый массив содержит правый? |
Левый массив содержится в правом? |
Выдаёт число элементов в массиве. |
Выдаёт индекс первого элемента, равного правому аргументу, или 0, если такого элемента нет. (Аналог функции |
Добавляет элемент в конец массива. |
Соединяет два массива. |
Удаляет из массива элементы, равные правому аргументу. |
Удаляет из левого массива элементы правого массива. |
Вычисляет объединение аргументов. |
Вычисляет объединение аргументов. |
Вычисляет пересечение аргументов. |
Массив удовлетворяет запросу? (см. ниже) |
Массив удовлетворяет запросу? (коммутирующий оператор к |
Операторы &&
, @>
и <@
равнозначны встроенным операторам PostgreSQL с теми же именами, за исключением того, что они работают только с целочисленными массивами, не содержащими NULL, тогда как встроенные операторы работают с массивами любых типов. Благодаря этому ограничению, в большинстве случаев они работают быстрее, чем встроенные операторы.
Операторы @@
и ~~
проверяют, удовлетворяет ли массив запросу, представляемому в виде значения специализированного типа данных query_int
. Запрос содержит целочисленные значения, сравниваемые с элементами массива, возможно с использованием операторов &
(AND), |
(OR) и !
(NOT). При необходимости могут использоваться скобки. Например, запросу 1&(2|3)
удовлетворяют запросы, которые содержат 1 и также содержат 2 или 3.
F.20.2. Поддержка индексов #
Модуль intarray
поддерживает индексы для операторов &&
, @>
, и @@
, а также обычную проверку равенства массивов.
Модуль предоставляет два параметризованных класса операторов GiST: gist__int_ops
(используется по умолчанию), подходящий для маленьких и средних по размеру наборов данных, и gist__intbig_ops
, применяющий сигнатуру большего размера и подходящий для индексации больших наборов данных (то есть столбцов, содержащих много различных значений массива). В этой реализации используется структура данных RD-дерева со встроенным сжатием с потерями.
Класс gist__int_ops
аппроксимирует набор целых чисел в виде массива диапазонов. В его необязательном целочисленном параметре numranges
можно задать максимальное число диапазонов в одном ключе индекса. Параметр может принимать значения от 1 до 253, по умолчанию он равен 100. При увеличении числа массивов, составляющих ключ индекса GiST, поиск работает точнее (сканируется меньшая область в индексе и меньше страниц кучи), но сам индекс становится больше.
Класс gist__intbig_ops
аппроксимирует набор целых чисел в виде сигнатуры битовой карты. В его необязательном целочисленном параметре siglen
можно задать размер сигнатуры в байтах. Параметр может принимать значения от 1 до 2024, по умолчанию он равен 16. При увеличении размера сигнатуры поиск работает точнее (сканируется меньшая область в индексе и меньше страниц кучи), но сам индекс становится больше.
Есть также нестандартный класс операторов GIN, gin__int_ops
, поддерживающий эти операторы наряду с <@
.
Выбор между индексами GiST и GIN зависит от относительных характеристик производительности GiST и GIN, которые здесь не рассматриваются.
F.20.3. Пример #
-- сообщение может относиться к одной или нескольким «секциям»
CREATE TABLE message (mid INT PRIMARY KEY, sections INT[], ...);
-- создать специализированный индекс с длиной сигнатуры 32 байта
CREATE INDEX message_rdtree_idx ON message USING GIST (sections gist__intbig_ops (siglen = 32));
-- вывести сообщения из секций 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.20.4. Тестирование производительности #
В каталоге исходного кода contrib/intarray/bench
содержится пакет тестов, которые можно провести на установленном сервере PostgreSQL. (Для этого нужно установить пакет DBD::Pg
.) Чтобы запустить эти тесты, выполните:
cd .../contrib/intarray/bench createdb TEST psql -c "CREATE EXTENSION intarray" TEST ./create_test.pl | psql TEST ./bench.pl
Скрипт bench.pl
принимает несколько аргументов, о которых можно узнать, запустив его без аргументов.
F.20.5. Авторы #
Разработку осуществили Фёдор Сигаев (<teodor@sigaev.ru>
) и Олег Бартунов (<oleg@sai.msu.su>
). Дополнительные сведения можно найти на странице http://www.sai.msu.su/~megera/postgres/gist/. Андрей Октябрьский проделал отличную работу, добавив новые функции и операторы.