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.