F.12. cube — многомерный кубический тип данных#

F.12. cube — многомерный кубический тип данных

F.12. cube — многомерный кубический тип данных #

Этот модуль реализует тип данных куб для представления многомерных кубов.

Этот модуль считается "доверенным", то есть его можно установить недоступным пользователям, у которых есть привилегия CREATE в текущей базе данных.

F.12.1. Синтаксис #

Таблица F.2 показывает допустимые внешние представления для типа куб. x, y и т.д. обозначают числа с плавающей точкой.

Таблица F.2. Внешние представления кубов

Внешний синтаксисЗначение
xОдномерная точка (или одномерный интервал нулевой длины)
(x)То же самое, что и выше
x1,x2,...,xnТочка в n-мерном пространстве, представленная внутренне как куб нулевого объема
(x1,x2,...,xn)То же самое, что и выше
(x),(y)Одномерный интервал, начинающийся с x и заканчивающийся на y или наоборот; порядок не имеет значения
[(x),(y)]То же самое, что и выше
(x1,...,xn),(y1,...,yn)Пространственный куб n-мерности, представленный парой противоположных углов
[(x1,...,xn),(y1,...,yn)]То же самое, что и выше

Не имеет значения, в каком порядке вводятся противоположные углы куба. Функции cube автоматически меняют значения, если это необходимо, чтобы создать однородное внутреннее представление нижний левый — верхний правый. Когда углы совпадают, cube хранит только один угол вместе с флагом точка, чтобы избежать пустого пространства.

Входные данные игнорируют пробелы, поэтому [(x),(y)] эквивалентно [ ( x ), ( y ) ].

F.12.2. Точность #

Значения хранятся внутренне в виде 64-битных чисел с плавающей точкой. Это означает, что числа с более чем около 16 значащими цифрами будут усечены.

F.12.3. Использование #

Таблица F.3 показывает специализированные операторы, предоставляемые для типа куб.

Таблица F.3. Операторы куба

Оператор

Описание

cube && cubeboolean

Перекрываются ли кубы?

cube @> cubeboolean

Содержит ли первый куб второй?

cube <@ cubeboolean

Содержится ли первый куб во втором?

cube -> integerfloat8

Извлекает n-ую координату куба (считая с 1).

cube ~> integerfloat8

Извлекает n-ую координату куба, считая следующим образом: n = 2 * k - 1 означает нижнюю границу k-ой размерности, n = 2 * k означает верхнюю границу k-ой размерности. Отрицательное значение n обозначает обратное значение соответствующей положительной координаты. Этот оператор предназначен для поддержки KNN-GiST.

cube <-> cubefloat8

Вычисляет евклидово расстояние между двумя кубами.

cube <#> cubefloat8

Вычисляет такси (метрика L-1) расстояние между двумя кубами.

cube <=> cubefloat8

Вычисляет расстояние Чебышева (метрика L-бесконечность) между двумя кубами.


В дополнение к вышеперечисленным операторам, для типа cube доступны обычные операторы сравнения, показанные в Таблица 9.1. Эти операторы сначала сравнивают первые координаты, а затем, если они равны, сравнивают вторые координаты и так далее. Они существуют в основном для поддержки класса операторов индекса b-tree для типа cube, что может быть полезно, например, если нужно установить ограничение UNIQUE на столбец типа cube. В противном случае, этот порядок не имеет большой практической пользы.

Модуль cube также предоставляет класс операторов индекса GiST для значений типа cube. Индекс GiST типа cube может использоваться для поиска значений с использованием операторов =, &&, @> и <@ в предложениях WHERE.

Кроме того, индекс GiST типа куб может использоваться для поиска ближайших соседей с помощью операторов метрики <->, <#> и <=> в предложениях ORDER BY. Например, ближайший сосед трехмерной точки (0.5, 0.5, 0.5) можно эффективно найти с помощью следующего запроса:

SELECT c FROM test ORDER BY c <-> cube(array[0.5,0.5,0.5]) LIMIT 1;

Оператор ~> также может быть использован для эффективного извлечения первых нескольких значений, отсортированных по выбранной координате. Например, чтобы получить первые несколько кубов, упорядоченных по возрастанию первой координаты (нижний левый угол), можно использовать следующий запрос:

SELECT c FROM test ORDER BY c ~> 1 LIMIT 5;

И чтобы получить 2-мерные кубы, упорядоченные по первой координате верхнего правого угла по убыванию:

SELECT c FROM test ORDER BY c ~> 3 DESC LIMIT 5;

Таблица F.4 показывает доступные функции.

Таблица F.4. Функции куба

Функция

Описание

Пример(ы)

cube ( float8 ) → cube

Создает одномерный куб с одинаковыми координатами.

cube(1)(1)

cube ( float8, float8 ) → cube

Создает одномерный куб.

cube(1, 2)(1),(2)

cube ( float8[] ) → cube

Создает куб нулевого объема, используя координаты, определенные массивом.

cube(ARRAY[1,2,3])(1, 2, 3)

cube ( float8[], float8[] ) → cube

Создает куб с верхним правым и нижним левым координатами, определенными двумя массивами, которые должны быть одинаковой длины.

cube(ARRAY[1,2], ARRAY[3,4])(1, 2),(3, 4)

cube ( cube, float8 ) → cube

Создает новый куб, добавляя измерение к существующему кубу с одинаковыми значениями для обоих концов новой координаты. Это полезно для построения кубов по частям из вычисленных значений.

cube('(1,2),(3,4)'::cube, 5)(1, 2, 5),(3, 4, 5)

cube ( cube, float8, float8 ) → cube

Создает новый куб, добавляя измерение к существующему кубу. Это полезно для построения кубов по частям из вычисленных значений.

cube('(1,2),(3,4)'::cube, 5, 6)(1, 2, 5),(3, 4, 6)

cube_dim ( cube ) → integer

Возвращает количество измерений куба.

cube_dim('(1,2),(3,4)')2

cube_ll_coord ( cube, integer ) → float8

Возвращает n-е значение координаты для нижнего левого угла куба.

cube_ll_coord('(1,2),(3,4)', 2)2

cube_ur_coord ( cube, integer ) → float8

Возвращает n-е значение координаты для верхнего правого угла куба.

cube_ur_coord('(1,2),(3,4)', 2)4

cube_is_point ( cube ) → boolean

Возвращает true, если куб является точкой, то есть, две определяющие углы совпадают.

cube_is_point(cube(1,1))t

cube_distance ( cube, cube ) → float8

Возвращает расстояние между двумя кубами. Если оба куба являются точками, это нормальная функция расстояния.

cube_distance('(1,2)', '(3,4)')2.8284271247461903

cube_subset ( cube, integer[] ) → cube

Создает новый куб из существующего куба, используя список индексов измерений из массива. Может использоваться для извлечения конечных точек одного измерения, удаления измерений или изменения их порядка по желанию.

cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[2])(3),(7)

cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1])(5, 3, 1, 1),(8, 7, 6, 6)

cube_union ( cube, cube ) → cube

Производит объединение двух кубов.

cube_union('(1,2)', '(3,4)')(1, 2),(3, 4)

cube_inter ( cube, cube ) → cube

Производит пересечение двух кубов.

cube_inter('(1,2)', '(3,4)')(3, 4),(1, 2)

cube_enlarge ( c cube, r double, n integer ) → cube

Увеличивает размер куба на указанный радиус r в не менее чем n измерениях. Если радиус отрицательный, то куб уменьшается. Все определенные измерения изменяются на радиус r. Координаты нижнего левого угла уменьшаются на r, а координаты верхнего правого угла увеличиваются на r. Если нижний левый угол увеличивается больше, чем соответствующий верхний правый угол (это может произойти только при r < 0), то оба угла устанавливаются в среднее значение. Если n больше количества определенных измерений и куб увеличивается (r > 0), то добавляются дополнительные измерения, чтобы всего было n; 0 используется в качестве начального значения для дополнительных координат. Эта функция полезна для создания ограничивающих рамок вокруг точки для поиска близлежащих точек.

cube_enlarge('(1,2),(3,4)', 0.5, 3)(0.5, 1.5, -0.5),(3.5, 4.5, 0.5)


F.12.4. По умолчанию #

Этот союз:

select cube_union('(0,5,2),(2,3,1)', '0');
cube_union
-------------------
(0, 0, 0),(2, 5, 2)
(1 row)

не противоречит здравому смыслу, как и пересечение:

select cube_inter('(0,-1),(1,1)', '(-2),(2)');
cube_inter
-------------
(0, 0),(1, 0)
(1 row)

Во всех бинарных операциях с кубами разной размерности, куб с меньшей размерностью считается декартовой проекцией, т.е. имеющей нули на месте координат, опущенных в строковом представлении. Приведенные выше примеры эквивалентны:

cube_union('(0,5,2),(2,3,1)','(0,0,0),(0,0,0)');
cube_inter('(0,-1),(1,1)','(-2,0),(2,0)');

Следующий предикат содержания использует синтаксис точки, в то время как внутреннее представление второго аргумента осуществляется с помощью прямоугольника (box). Этот синтаксис позволяет избежать необходимости определения отдельного типа точки и функций для предикатов (box, точка).

select cube_contains('(0,0),(1,1)', '0.5,0.5');
cube_contains
--------------
t
(1 row)

F.12.5. Примечания #

Для примеров использования смотрите тест регрессии sql/cube.sql.

Для того чтобы затруднить возможность поломки, существует ограничение в 100 на количество измерений кубов. Это установлено в файле cubedata.h, если вам нужно что-то большее.

F.12.6. Заслуги #

Оригинальный автор: Ген Селков, мл. , Отделение математики и компьютерных наук, Национальная лаборатория Аргонн.

Мои благодарности в первую очередь идут профессору Джо Хеллерштейну (https://dsf.berkeley.edu/jmh/) за ясное изложение сути GiST (http://gist.cs.berkeley.edu/), а также его бывшему студенту Энди Донгу за его пример, написанный для Illustra. Я также благодарен всем разработчикам Postgres, настоящим и прошлым, за возможность создать свой собственный мир и жить в нем непрерывно. И я хотел бы выразить свою благодарность Аргоннской лаборатории и Министерству энергетики США за годы верной поддержки моих исследований в области баз данных.

Незначительные обновления этого пакета были сделаны Бруно Вольфом III в августе/сентябре 2002 года. Они включают изменение точности с одинарной на двойную и добавление некоторых новых функций.

Дополнительные обновления были внесены Joshua Reich в июле 2006 года. Они включают функцию cube(float8[], float8[]) и очистку кода для использования протокола вызова V1 вместо устаревшего протокола V0.