受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

F.17. intarray #

intarray模块提供了一些有用的函数和操作符,用于操作不含 NULL 的整数数组。它还支持使用其中某些操作符进行索引搜索。

如果所提供的数组中包含任何 NULL 元素,所有这些操作都会抛出错误。

这些操作中有许多只对一维数组才有意义。尽管它们也接受更高维度的输入 数组,但数据会被视为按存储顺序排列的线性数组。

该模块被视为受信任的,也就是说,拥有当前数据库 CREATE权限的非超级用户也可以安装它。

F.17.1. intarray 函数和操作符 #

intarray模块提供的函数列在Table F.8中, 操作符列在Table F.9中。

Table F.8. intarray 函数

函数

描述

示例

icount ( integer[] ) → integer

返回数组中的元素个数。

icount('{1,2,3}'::integer[])3

sort ( integer[], dir text ) → integer[]

按升序或降序对数组排序。dir必须为 ascdesc

sort('{1,3,2}'::integer[], 'desc'){3,2,1}

sort ( integer[] ) → integer[]

sort_asc ( integer[] ) → integer[]

按升序排序。

sort(array[11,77,44]){11,44,77}

sort_desc ( integer[] ) → integer[]

按降序排序。

sort_desc(array[11,77,44]){77,44,11}

uniq ( integer[] ) → integer[]

移除相邻的重复项。常与sort一起使用,以移除 所有重复项。

uniq('{1,2,2,3,1,1}'::integer[]){1,2,3,1}

uniq(sort('{1,2,3,2,1}'::integer[])){1,2,3}

idx ( integer[], item integer ) → integer

返回第一个与item匹配的数组元素的索引,若无 匹配则返回 0。

idx(array[11,22,33,22,11], 22)2

subarray ( integer[], start integer, len integer ) → integer[]

提取数组中从位置start开始、长度为 len个元素的部分。

subarray('{1,2,3,2,1}'::integer[], 2, 3){2,3,2}

subarray ( integer[], start integer ) → integer[]

提取数组中从位置start开始的部分。

subarray('{1,2,3,2,1}'::integer[], 2){2,3,2,1}

intset ( integer ) → integer[]

创建一个只含一个元素的数组。

intset(42){42}


Table F.9. intarray 操作符

操作符

描述

integer[] && integer[]boolean

数组是否重叠(至少有一个共同元素)?

integer[] @> integer[]boolean

左数组是否包含右数组?

integer[] <@ integer[]boolean

左数组是否包含在右数组中?

# integer[]integer

返回数组中的元素个数。

integer[] # integerinteger

返回第一个与右操作数匹配的数组元素的索引,若无匹配则返回 0。 (与idx函数相同。)

integer[] + integerinteger[]

将元素添加到数组末尾。

integer[] + integer[]integer[]

将这些数组连接起来。

integer[] - integerinteger[]

从数组中移除与右操作数匹配的项。

integer[] - integer[]integer[]

从左数组中移除右数组中的元素。

integer[] | integerinteger[]

计算参数的并集。

integer[] | integer[]integer[]

计算参数的并集。

integer[] & integer[]integer[]

计算参数的交集。

integer[] @@ query_intboolean

数组是否满足查询?(见下文)

query_int ~~ integer[]boolean

数组是否满足查询?(@@的交换子)


操作符&&@><@等价于PostgreSQL内置的 同名操作符,不同之处在于它们只适用于不包含 NULL 的整数数组,而内置 操作符适用于任何数组类型。这一限制使它们在很多情况下比内置操作符更快。

@@~~操作符用于测试数组是否满足某个 查询,该查询表示为专用数据类型query_int 的一个值。一个查询由若干整数值组成,这些值会与 数组元素进行检查,并且可通过操作符&(AND)、 |(OR)和!(NOT)组合起来。必要时 可以使用括号。例如,查询1&(2|3)可匹配包含 1 且还包含 2 或 3 之一的数组。

F.17.2. 索引支持 #

intarray&&@>@@操作符以及常规的数组相等运算 提供索引支持。

提供了两个带参数的 GiST 索引操作符类:默认使用的 gist__int_ops适用于小到中等规模的数据集,而 gist__intbig_ops使用较大的签名,更适合为大型数据集 建立索引(即列中包含大量不同数组值的数据集)。该实现使用 RD-tree 数据结构,并带有内置的有损压缩。

gist__int_ops将整数集近似表示为整数范围数组。其可选 整数参数numranges决定单个索引键中的最大范围数。 numranges的默认值是 100,有效值在 1 到 253 之间。 使用更大的数组作为 GiST 索引键会带来更精确的搜索(扫描索引的较小部分 和较少的堆页),代价是索引会更大。

gist__intbig_ops将整数集近似表示为位图签名。其可选 整数参数siglen决定签名长度(以字节为单位)。默认 签名长度为 16 字节,签名长度的有效值在 1 到 2024 字节之间。更长的 签名会带来更精确的搜索(扫描索引的较小部分和较少的堆页),代价是 索引会更大。

另有一个非默认的 GIN 操作符类gin__int_ops,它除了 支持这些操作符外,还支持<@

在 GiST 和 GIN 索引之间如何选择,取决于二者的相对性能特征,相关讨论 见其他部分。

F.17.3. 示例 #

-- a message can be in one or more sections
CREATE TABLE message (mid INT PRIMARY KEY, sections INT[], ...);

-- create specialized index with signature length of 32 bytes
CREATE INDEX message_rdtree_idx ON message USING GIST (sections gist__intbig_ops (siglen = 32));

-- select messages in section 1 OR 2 - OVERLAP operator
SELECT message.mid FROM message WHERE message.sections && '{1,2}';

-- select messages in sections 1 AND 2 - CONTAINS operator
SELECT message.mid FROM message WHERE message.sections @> '{1,2}';

-- the same, using QUERY operator
SELECT message.mid FROM message WHERE message.sections @@ '1&2'::query_int;

F.17.4. 基准测试 #

源代码目录contrib/intarray/bench包含一个基准测试 套件,可以针对一个已安装的PostgreSQL服务器 运行。(还要求已安装DBD::Pg。)运行方式如下:

cd .../contrib/intarray/bench
createdb TEST
psql -c "CREATE EXTENSION intarray" TEST
./create_test.pl | psql TEST
./bench.pl

bench.pl脚本有很多选项,在不带任何参数运行时会显示 这些选项。

F.17.5. 作者 #

所有工作都由 Teodor Sigaev()和 Oleg Bartunov()完成。更多信息请见 http://www.sai.msu.su/~megera/postgres/gist/。 Andrey Oktyabrski 在添加新函数和新操作方面也做出了很大贡献。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。