这个模块实现了一种数据类型cube
来表示多维立方体。
此模块被视为“trusted”,也就是说,它可以由在当前数据库上具有 CREATE
权限的非超级用户安装。
表 F.2展示了cube
类型有效的外部表示。x
、y
等表示浮点数。
表 F.2. 立方体外部表示
外部语法 | 含义 |
---|---|
| 一个一维点(或者长度为零的一维区间) |
( | 同上 |
| n-维空间中的一个点,内部表示为一个零容积立方体 |
( | 同上 |
( | 开始于x 并且结束于y 的一个一维区间,反之亦然。顺序并不重要
|
[( | 同上 |
( | 一个 n-维立方体,用它的对角顶点对表示 |
[( | 同上 |
一个立方体的对角录入的顺序无关紧要。如果需要创建一种统一的“左下 — 右上”的内部表示,cube
函数会自动地交换值。当角重合时,cube
只存储一个角和一个“is point”标志,这样避免浪费空间。
输入中的空白空间会被忽略,因此[(
与x
),(y
)][ (
相同。
x
), ( y
) ]
值在内部被存储为 64 位浮点数。这意味着超过 16 位有效位的数字将被截断。
表 F.3展示了为类型cube
提供的专用的操作符。
表 F.3. 立方体操作符
操作符 描述 |
---|
立方体是否有重叠? |
第一个立方体是否包含第二个立方体? |
第一个立方体是否包含在第二个立方体里面? |
提取立方体的第 |
提取立方体的第 |
计算两个立方体之间的欧几里德距离. |
计算两个立方体之间的直线(L-1 度量)距离。 |
计算两个立方体之间的切比雪夫(L-inf 度量)距离. |
(在 PostgreSQL 8.2 之前,包含操作符@>
和<@
分别被称为@
和~
。这些名称仍然可用,但是已经被废弃并且最终将会退休。注意旧的名字与之前核心几何数据类型遵循的习惯相反!)
除上述操作符外,表 9.1 中显示的常用比较操作符也可用于cube
类型。
这些操作符首先比较第一个坐标,如果它们相等再比较第二个坐标等等。
它们主要为支持cube
的 b树索引操作符类而存在,这类操作符对支持cube
列上的 UNIQUE 约束等很有用。
否则,这种排序没有太大的实际作用。
cube
模块也为cube
值提供了一个 GiST 索引操作符类。cube
GiST 索引可以被用于在WHERE
子句中通过=
、&&
、@>
以及<@
操作符来搜索值。
此外,cube
GiST 索引可以被用在ORDER BY
子句中通过度量操作符<->
、<#>
和<=>
来查找最近邻。例如, 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.4展示了可用的函数。
表 F.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)
用法的例子可见回归测试sql/cube.sql
。
为了不容易出问题,对于立方体的维度数有 100 的限制。如果你想要更大的立方体,可以在cubedata.h
中修改。
原作者:Gene Selkov, Jr. <selkovjr@mcs.anl.gov>
,数学与计算机科学部,阿尔贡国家实验室。
我的感谢主要要献给 Joe Hellerstein 教授(https://dsf.berkeley.edu/jmh/),他阐明了 GiST (http://gist.cs.berkeley.edu/),还要送给他以前的学生 Andy Dong,他为 Illustra 编写了例子。 我也对所有的 Postgres 开发者(现在的和以前的)心存感激,他们让我能够创造自己的世界并且宁静地生活在其中。 我也要感谢阿尔贡实验室和美国能源局对我多年数据库研究的支持。
这个包的小更新由 Bruno Wolff III <bruno@wolff.to>
于 2002 年 8/9 月完成。这些修改包括将精度从单精度改为双精度以及增加了一些新的函数。
额外的更新由 Joshua Reich <josh@root.net>
在 2006 年 7 月做出。其中包括cube(float8[], float8[])
并且将代码从废弃的 V0 协议改到 V1 调用协议。