Документация по PostgreSQL 9.4.1 | |||
---|---|---|---|
Пред. | Уровень выше | Приложение E. Дополнительно поставляемые модули | След. |
E.18. intarray
Модуль intarray предоставляет ряд полезных функций и операторов для работы с массивами целых чисел без NULL. Также он поддерживает поиск по индексу для некоторых из этих операторов.
Все эти операции выдают ошибку, если в передаваемом массиве оказываются значения NULL.
Многие из этих операций имеют смысл только с одномерными массивами. Хоти им можно передать входной массив и большей размерности, значения будут считываться из него как из линейного массива в порядке хранения.
E.18.1. Функции и операторы intarray
Реализованные в модуле intarray функции перечислены в Таблице E-8, а операторы — в Таблице E-9.
Таблица E-8. Функции intarray
Функция | Тип результата | Описание | Пример | Результат |
---|---|---|---|---|
icount(int[]) | int | число элементов в массиве | icount('{1,2,3}'::int[]) | 3 |
sort(int[], text dir) | int[] | сортирует массив — в dir должно задаваться asc (по возрастанию) или desc (по убыванию) | sort('{1,2,3}'::int[], 'desc') | {3,2,1} |
sort(int[]) | int[] | сортирует в порядке возрастания | sort(array[11,77,44]) | {11,44,77} |
sort_asc(int[]) | int[] | сортирует в порядке возрастания | ||
sort_desc(int[]) | int[] | сортирует в порядке убывания | ||
uniq(int[]) | int[] | удаляет дубликаты | uniq(sort('{1,2,3,2,1}'::int[])) | {1,2,3} |
idx(int[], int item) | int | индекс первого элемента, равного item (0, если такого нет) | idx(array[11,22,33,22,11], 22) | 2 |
subarray(int[], int start, int len) | int[] | часть массива, начинающаяся с позиции start и состоящая из len элементов | subarray('{1,2,3,2,1}'::int[], 2, 3) | {2,3,2} |
subarray(int[], int start) | int[] | часть массива, начинающаяся с позиции start | subarray('{1,2,3,2,1}'::int[], 2) | {2,3,2,1} |
intset(int) | int[] | создаёт массив с одним элементом | intset(42) | {42} |
Таблица E-9. Операторы 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 операторы включения @> и <@ обозначались соответственно как @ и ~. Эти имена по-прежнему действуют, но считаются устаревшими и в конце концов будут упразднены. Заметьте, что старые имена произошли из соглашения, которому раньше следовали ключевые геометрические типы данных!)
Операторы &&, @> и <@ равнозначны встроенным операторам PostgreSQL с теми же именами, за исключением того, что они работают только с целочисленными массивами, не содержащими NULL, тогда как встроенные операторы работают с массивами любых типов. Благодаря этому ограничению, в большинстве случаев они работают быстрее, чем встроенные операторы.
Операторы @@ и ~~ проверяют, удовлетворяет ли массив запросу, представляемому в виде значения специализированного типа данных query_int. Запрос содержит целочисленные значения, сравниваемые с элементами массива, возможно с использованием операторов & (AND), | (OR) и ! (NOT). При необходимости могут использоваться скобки. Например, запросу 1&(2|3) удовлетворяют запросы, которые содержат 1 и также содержат 2 или 3.
E.18.2. Поддержка индексов
Модуль intarray поддерживает индексы для операторов &&, @>, <@ и @@, а также обычную проверку равенства массивов.
Модуль предоставляет два класса операторов GiST: gist__int_ops (используется по умолчанию), подходящий для маленьких и средних по размеру наборов данных, и gist__intbig_ops, применяющий сигнатуру большего размера и подходящий для индексации больших наборов данных (то есть колонок, содержащих много различных значений массива). В этой реализации используется структура данных RD-дерева со встроенным сжатием с потерями.
Есть также нестандартный класс операторов GIN, gin__int_ops, поддерживающий те же операторы.
Выбор между индексами GiST и GIN зависит от относительных характеристик производительности GiST и GIN, которые здесь не рассматриваются. Как правило, индекс GIN быстрее индекса GiST при поиске, но строится или обновляется он медленнее; поэтому GIN лучше подходит для статических, а GiST для часто изменяемых данных.
E.18.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;
E.18.4. Тестирование производительности
В каталоге исходного кода contrib/intarray/bench содержится набор тестов производительности. Чтобы запустить эти тесты, выполните:
cd .../bench createdb TEST psql TEST < ../_int.sql ./create_test.pl | psql TEST ./bench.pl
Скрипт bench.pl принимает несколько аргументов, о которых можно узнать, запустив его без аргументов.
E.18.5. Авторы
Разработку осуществили Фёдор Сигаев (<teodor@sigaev.ru>
) и Олег Бартунов (<oleg@sai.msu.su>
). Дополнительные сведения можно найти на странице http://www.sai.msu.su/~megera/postgres/gist/. Андрей Октябрьский проделал отличную работу, добавив новые функции и операторы.
Пред. | Начало | След. |
intagg | Уровень выше | isn |