Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

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

F.10.1. 语法
F.10.2. 精度
F.10.3. 用法
F.10.4. 默认值
F.10.5. 注意
F.10.6. 来源

此模块通过数据类型 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. 立方体运算符

运算符

说明

立方体 && 立方体布尔

这些立方体是否重叠?

立方体 @> 立方体布尔

第一个立方体是否包含第二个立方体?

立方体 <@ 立方体布尔

第一个立方体是否包含在第二个立方体中?

立方体 -> 整数float8

提取立方体的第n个坐标(从 1 开始计数)。

立方体 ~> 整数float8

按以下方式提取立方体的第n个坐标:n = 2 * k - 1 表示第k个维度的下限,n = 2 * k 表示第k个维度的上限。负n表示相应正坐标的逆值。此运算符专用于支持 KNN-GiST。

立方体 <-> 立方体float8

计算两个立方体之间的欧几里得距离。

立方体 <#> 立方体float8

计算两个立方体之间的出租车(L-1 指标)距离。

立方体 <=> 立方体float8

计算两个立方体之间的切比雪夫(L-inf 指标)距离。


除了以上运算符外,表 9.1 中显示的常用比较运算符也可用于类型立方体。这些运算符先比较第一个坐标,如果相同,则比较第二个坐标,以此类推。它们主要用于支持立方体的 B 树索引运算符类,例如,如果您想对立方体列使用 UNIQUE 约束,这就会很有用。否则,这种排序在实际中不是很有用。

cube” 模块还支持 cube 值的 GiST 索引操作类。可以通过 WHERE 子句中的 =&&@><@ 操作符,利用 cube GiST 索引来查找值。

此外,可以通过 ORDER BY 子句中的度量操作符 <-><#><=> 利用 cube GiST 索引来找到近邻。例如,可以使用以下方式有效地找到 3-D 点 (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-D 立方体进行降序排列

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)

对于所有涉及不同维度立方体的二元运算,维度较低的一方都被视作是笛卡尔投影,也就是说,在字符串表示形式中省略的坐标处具有 0 的值。以上示例等价于

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. ,数学与计算机科学分部,Argonne 国家实验室。

首先感谢 Prof. Joe Hellerstein(https://dsf.berkeley.edu/jmh/)阐明了 GiST(http://gist.cs.berkeley.edu/)要点,及其前学生 Andy Dong 为 Illustra 编写的示例。同时感谢所有 PostgreSQL 开发者,无论是过去还是现在,让我能够创建自己的世界并平静地生活在其中。我还希望感谢 Argonne Lab 和美国能源部多年来对我的数据库研究的忠实支持。

此软件包的次要更新由 Bruno Wolff III 于 2002 年 8 月/9 月完成。这些更新包括将精度从单精度更改为双精度并添加一些新功能。

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