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
.