选择 打开 改范围 完整检索页
受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10
当前 PostgreSQL 版本不在支持生命周期内。
您可以参阅当前版本的对应页面,或其他在上面列出的活跃大版本。

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

该模块实现了用于表示多维立方体的cube数据类型。

F.9.1. 语法

Table F.2展示了cube类型合法的外部表示。 xy等表示浮点数。

Table F.2. cube 外部表示

外部语法 含义
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只存储其中一个角点,并附带一个is point标志, 以避免浪费空间。

输入时会忽略空白字符,因此 [(x),(y)][ ( x ), ( y ) ] 相同。

F.9.2. 精度

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

F.9.3. 用法

Table F.3展示了为cube类型提供的操作符。

Table F.3. cube 操作符

操作符 结果 描述
a = b boolean 立方体 a 和 b 相同。
a && b boolean 立方体 a 和 b 重叠。
a @> b boolean 立方体 a 包含立方体 b。
a <@ b boolean 立方体 a 包含在立方体 b 中。
a < b boolean 立方体 a 小于立方体 b。
a <= b boolean 立方体 a 小于或等于立方体 b。
a > b boolean 立方体 a 大于立方体 b。
a >= b boolean 立方体 a 大于或等于立方体 b。
a <> b boolean 立方体 a 不等于立方体 b。
a -> n float8 获取立方体的第 n 个坐标(从 1 开始计数)。
a ~> n float8 按以下方式获取立方体的第 n 个坐标:n = 2 * k - 1 表示第 k 维的下界,n = 2 * k 表示第 k 维的上界。负的 n 表示相应正坐标值的相反数。该操作符专为支持 KNN-GiST 而设计。
a <-> b float8 a 和 b 之间的欧几里得距离。
a <#> b float8 a 和 b 之间的出租车距离(L-1 度量)。
a <=> b float8 a 和 b 之间的切比雪夫距离(L-无穷度量)。

(在 PostgreSQL 8.2 之前,包含操作符 @><@ 分别称为 @~。这些名称仍然可用,但已弃用,最终将被删除。请注意,旧名称与核心几何数据类型以前采用的约定正好相反!)

标量排序操作符(<>= 等)除了排序之外,在实际用途上没有太大意义。这些操作符首先比较第一个坐标;如果相等,再比较第二个坐标,依此类推。它们主要用于支持cube的 B-树索引操作符类,例如,当你希望在cube列上设置 UNIQUE 约束时可能会有用。

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

此外,cube GiST 索引还可用于在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;

要获得按右上角第一个坐标降序排列的二维立方体,可以使用:

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

Table F.4展示了可用函数。

Table F.4. cube 函数

函数 结果 描述 示例
cube(float8) cube 创建一个一维立方体,其两个坐标相同。 cube(1) == '(1)'
cube(float8, float8) cube 创建一个一维立方体。 cube(1,2) == '(1),(2)'
cube(float8[]) cube 根据数组定义的坐标创建一个零体积立方体。 cube(ARRAY[1,2]) == '(1,2)'
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_distance(cube, cube) float8 返回两个立方体之间的距离。如果两个立方体都是点,这就是普通的距离函数。
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_inter(cube, cube) cube 生成两个立方体的交集。
cube_enlarge(c cube, r double, n integer) cube 将立方体至少 n 个维度的大小增加指定半径 r。如果半径为负,则改为缩小立方体。所有已定义的维度都会按半径 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.9.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)');

下面的包含谓词使用的是点语法,但实际上第二个参数在内部表示为一个 box。 这种语法使我们无须单独定义点类型以及用于 (box,point) 谓词的函数。

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

F.9.5. 注意

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

为了避免用户轻易把事情弄坏,立方体的维数上限被设为 100。 如果需要更大的值,可在cubedata.h中修改该限制。

F.9.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 协议。