intarray — работа с массивами целых чисел
Эта страница переведена при помощи нейросети GigaChat.
Модуль intarray
предоставляет ряд полезных функций и операторов для работы с массивами целых чисел без нулевых значений. Также поддерживается выполнение индексированных поисков с использованием некоторых из этих операторов.
Все эти операции вызовут ошибку, если предоставленный массив содержит какие-либо элементы NULL.
Многие из этих операций имеют смысл только для одномерных массивов. Хотя они будут принимать входные массивы с большим количеством измерений, данные обрабатываются так, как будто это линейный массив в порядке хранения.
Этот модуль считается «доверенным», то есть его могут устанавливать неподключенные пользователи, которые имеют привилегию CREATE
на текущей базе данных.
Функции и операторы intarray
Функции, предоставляемые модулем, показаны в таблице «Функции intarray», а операторы - в таблице «Операторы intarray».
Функции intarray:
Функция | Описание | Пример(ы) |
---|---|---|
icount ( integer[] ) → integer | Возвращает количество элементов в массиве | icount('{1,2,3}'::integer[]) → 3 |
sort ( integer[] ,dir - text ) → integer[] | Сортирует массив в порядке возрастания или убывания. dir должно быть равно asc или desc | sort('{1,3,2}'::integer[], 'desc') → {3,2,1} |
sort ( integer[] ) → integer[] | sort_asc ( integer[] ) → integer[] | Сортировка по возрастанию | sort(array[11,77,44]) → {11,44,77} |
sort_desc ( integer[] ) → integer[] | Сортировка по убыванию | sort_desc(array[11,77,44]) → {77,44,11} |
uniq ( integer[] ) → integer[] | Удаляет соседние дубликаты. Часто используется с sort для удаления всех дубликатов | uniq('{1,2,2,3,1,1}'::integer[]) → {1,2,3,1} | uniq(sort('{1,2,3,2,1}'::integer[])) → {1,2,3} |
idx ( integer[] , item - integer ) → integer | Возвращает индекс первого элемента массива, соответствующего item , или 0, если нет совпадения | idx(array[11,22,33,22,11], 22) → 2 |
subarray ( integer[] , start - integer , len - integer ) → integer[] | Извлекает часть массива, начиная с позиции start , с элементами len | subarray('{1,2,3,2,1}'::integer[], 2, 3) → {2,3,2} |
subarray ( integer[] ,start - integer ) → integer[] | Извлекает часть массива, начиная с позиции start | subarray('{1,2,3,2,1}'::integer[], 2) → {2,3,2,1} |
intset ( integer ) → integer[] | Создает массив с одним элементом | intset(42) → {42} |
Операторы intarray:
Оператор | Описание |
---|---|
integer[] && integer[] → boolean | Пересекаются ли массивы (имеют хотя бы один общий элемент)? |
integer[] @> integer[] → boolean | Содержит ли левый массив правый массив? |
integer[] <@ integer[] → boolean | Вложен ли левый массив в правый массив? |
# integer[] → integer | Возвращает количество элементов в массиве |
integer[] # integer → integer | Возвращает индекс первого элемента массива, соответствующего правому аргументу, или 0, если совпадений нет. (То же самое, что и функция idx .) |
integer[] + integer → integer[] | Добавляет элемент в конец массива |
integer[] + integer[] → integer[] | Конкатенирует массивы |
integer[] - integer → integer[] | Удаляет записи, соответствующие правому аргументу из массива |
integer[] - integer[] → integer[] | Удаляет элементы правого массива из левого массива |
integer[] | integer → integer[] | Вычисляет объединение аргументов |
integer[] | integer[] → integer[] | Вычисляет объединение аргументов |
integer[] & integer[] → integer[] | Вычисляет пересечение аргументов |
integer[] @@ query_int → boolean | Удовлетворяет ли массив запросу? (см. ниже) |
query_int ~~ integer[] → boolean | Удовлетворяет ли массив запросу? (коммутатор @@ ) |
Операторы &&
, @>
и <@
эквивалентны встроенным операторам PostgreSQL с теми же именами, за исключением того, что они работают только с целочисленными массивами, которые не содержат нулей, тогда как встроенные операторы работают для любого типа массива. Это ограничение делает их быстрее, чем встроенные операторы во многих случаях.
Операторы @@
и ~~
проверяют, удовлетворяет ли массив запросу , который выражается значением специализированного типа данных query_int
. Запрос состоит из целочисленных значений, которые проверяются на соответствие элементам массива, возможно, объединенных с использованием операторов &
(И), |
(ИЛИ) и !
(НЕ). Скобки могут использоваться при необходимости. Например, запрос 1&(2|3)
соответствует массивам, содержащим 1 и также содержащим либо 2, либо 3.
Поддержка индексов
intarray
поддерживает индексы для операторов &&
, @>
, и @@
, а также обычное равенство массивов.
Предоставляются два параметризированных класса операторов GiST-индекса: gist__int_ops
(используется по умолчанию) подходит для небольших и средних наборов данных, тогда как gist__intbig_ops
использует большую подпись и более подходит для индексирования больших наборов данных (т.е. столбцов, содержащих большое количество различных значений массива). Реализация использует структуру данных RD-дерева со встроенным сжатием с потерями.
gist__int_ops
аппроксимирует множество целых чисел как массив целых диапазонов. Его необязательный целочисленный параметр numranges
определяет максимальное количество диапазонов в одном индексе ключа. Значение по умолчанию для numranges
равно 100. Допустимые значения находятся между 1 и 253. Использование больших массивов в качестве ключей индекса GiST приводит к более точному поиску (сканированию меньшей доли индекса и меньшего количества страниц кучи) за счет увеличения размера индекса.
gist__intbig_ops
аппроксимирует множество целых чисел в виде сигнатуры битовой карты. Его необязательный целочисленный параметр siglen
определяет длину подписи в байтах. Длина подписи по умолчанию составляет 16 байт. Допустимая длина подписи варьируется от 1 до 2024 байт. Более длинные подписи приводят к более точному поиску (сканируя меньшую долю индекса и меньше страниц кучи), но увеличивают размер индекса.
Существует также нестандартный класс операторов GIN gin__int_ops
, который поддерживает эти операторы, а также <@
.
Выбор между индексированием GiST и GIN зависит от относительных характеристик производительности GiST и GIN, которые обсуждаются в другом месте.
Пример
-- a message can be in one or more “sections”
CREATE TABLE message (mid INT PRIMARY KEY, sections INT[], ...);
-- create specialized index with signature length of 32 bytes
CREATE INDEX message_rdtree_idx ON message USING GIST (sections gist__intbig_ops (siglen = 32));
-- select messages in section 1 OR 2 - OVERLAP operator
SELECT message.mid FROM message WHERE message.sections && '{1,2}';
-- select messages in sections 1 AND 2 - CONTAINS operator
SELECT message.mid FROM message WHERE message.sections @> '{1,2}';
-- the same, using QUERY operator
SELECT message.mid FROM message WHERE message.sections @@ '1&2'::query_int;
Тестирование производительности
Каталог 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
имеет множество опций, которые отображаются при его запуске без аргументов.