Перейти к основному содержимому

cube — тип данных для представления многомерных кубов

примечание

Эта страница переведена при помощи нейросети GigaChat.

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

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

Синтаксис

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

Внешние представления кубов:

Внешний синтаксисЗначение
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 ) ].

Точность

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

Использование

Таблица «Операторы кубов» показывает специализированные операторы, предоставляемые для типа cube.

Операторы кубов:

ОператорОписание
cube && cube → booleanПересекаются ли кубы?
cube @> cube → booleanСодержит ли первый куб второй?
cube <@ cube → booleanСодержится ли первый куб во втором?
cube -> integer → float8Извлекает n-ю координату куба (считая от 1)
cube ~> integer → float8Извлекает n-ю координату куба, подсчитывая следующим образом: n = 2 * k - 1 означает нижнюю границу k-го измерения, n = 2 * k означает верхнюю границу k-го измерения. Отрицательное значение n обозначает значение, обратное соответствующей положительной координате. Этот оператор предназначен для поддержки KNN-GiST
cube <-> cube → float8Вычисляет евклидово расстояние между двумя кубами
cube <#> cube → float8Вычисляет расстояние городских кварталов (метрика L-1) между двумя кубами
cube <=> cube → float8Вычисляет расстояние Чебышева (метрическая L-бесконечность) между двумя кубами

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

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

Кроме того, индекс GiST cube можно использовать для нахождения ближайших соседей с помощью метрических операторов <->, <#> и <=> в предложениях 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;

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

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

Таблица «Функции для работы с кубами» показывает доступные функции.

Функции для работы с кубами:

ФункцияОписаниеПримеры
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Возвращает истину, если куб является точкой, то есть два определяющих угла одинаковы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)

Значения по умолчанию

Я считаю, что этот объединение:

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)');

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

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

Примечания

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

Во избежание некорректного применения этого типа, существует ограничение равное 100 на количество измерений кубов. Его можно изменить в cubedata.h.