2024 年 9 月 26 日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

F.10. cube — 多维立方体数据类型 #

此模块实现了一个数据类型 cube,用于表示多维立方体。

此模块被认为是 可信的,也就是说,非超级用户如果对当前数据库具有 CREATE 权限,则可以安装它。

F.10.1. 语法 #

表 F.1 显示了 cube 类型的有效外部表示。 xy 等表示浮点数。

表 F.1. 立方体外部表示

外部语法 含义
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.10.2. 精度 #

值在内部存储为 64 位浮点数。 这意味着超过大约 16 位有效数字的数字将被截断。

F.10.3. 用法 #

表 F.2 显示了为 cube 类型提供的专用运算符。

表 F.2. 立方体运算符

运算符

描述

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-inf 度量)距离。


除了上述运算符之外,表 9.1 中显示的常用比较运算符也适用于 cube 类型。 这些运算符首先比较第一个坐标,如果它们相等,则比较第二个坐标,依此类推。 它们主要存在是为了支持 cube 的 b 树索引运算符类,这在您希望对 cube 列进行 UNIQUE 约束时可能会有用。 否则,这种排序在实际应用中意义不大。

cube 模块还为 cube 值提供了一个 GiST 索引运算符类。 cube GiST 索引可用于使用 =&&@><@ 运算符在 WHERE 子句中搜索值。

此外, cube GiST 索引可用于使用度量运算符 <-><#><=>ORDER BY 子句中查找最近邻。 例如,可以有效地找到 3 维点 (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;

要获取按右上角的第一个坐标降序排列的二维立方体:

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

表 F.3 显示了可用函数。

表 F.3. 立方体函数

函数

描述

示例

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

以下包含谓词使用点语法,而实际上第二个参数在内部由一个框表示。此语法使定义单独的点类型和(框,点)谓词函数变得不必要。

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

F.10.5. 说明 #

有关用法的示例,请参见回归测试 sql/cube.sql

为了防止人们破坏事物,立方体的维度数量限制为 100。如果您需要更大的数量,则可以在 cubedata.h 中设置此限制。

F.10.6. 致谢 #

原始作者:Gene Selkov, Jr. ,阿贡国家实验室数学与计算机科学部。

我主要感谢 Joe Hellerstein 教授 (https://dsf.berkeley.edu/jmh/) 为我阐明了 GiST (http://gist.cs.berkeley.edu/) 的要旨,并感谢他以前的学生 Andy Dong 为 Illustra 编写的示例。我还感谢所有过去和现在的 Postgres 开发人员,他们使我能够创造自己的世界并在其中不受干扰地生活。最后,我要感谢阿贡实验室和美国能源部多年来对我数据库研究的忠实支持。

Bruno Wolff III 在 2002 年 8 月/9 月对该软件包进行了少量更新。这些更新包括将精度从单精度更改为双精度,并添加了一些新函数。

Joshua Reich 在 2006 年 7 月进行了其他更新。这些更新包括 cube(float8[], float8[]),以及清理代码以使用 V1 调用协议而不是已弃用的 V0 协议。

提交更正

如果您在文档中发现任何错误,与您对特定功能的体验不符,或需要进一步澄清,请使用 此表单 报告文档问题。