PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

F.19. intarray — 操作整型数组 #

F.19.1. intarray 函数与操作符
F.19.2. 索引支持
F.19.3. 示例
F.19.4. 基准测试
F.19.5. 作者

intarray 模块提供多个用于操作不含空值的整型数组的实用函数与操作符。其中部分操作符还支持索引搜索。

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

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

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

F.19.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 必须是 asc 或 desc。

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[] # integer → integer

返回第一个与右参数匹配的数组元素的索引;如果没有匹配则返回 0。(与 idx 函数相同。)

integer[] + integer → integer[]

将元素添加到数组末尾。

integer[] + integer[] → integer[]

连接两个数组。

integer[] - integer → integer[]

从数组中移除与右参数匹配的条目。

integer[] - integer[] → integer[]

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

integer[] | integer → integer[]

计算参数的并集。

integer[] | integer[] → integer[]

计算参数的并集。

integer[] & integer[] → integer[]

计算参数的交集。

integer[] @@ query_int → boolean

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

query_int ~~ integer[] → boolean

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


操作符 &&、@> 与 <@ 等效于 PostgreSQL 的同名内置操作符,区别在于它们只适用于不含空值的整型数组,而内置操作符适用于任意数组类型。这一限制使它们在许多情况下比内置操作符更快。

@@ 与 ~~ 操作符测试数组是否满足一个 查询,查询表示为专用数据类型 query_int 的值。查询由与数组元素进行比对的整数值构成,可以使用操作符 &(AND)、|(OR)与 !(NOT)组合,并按需使用圆括号。例如,查询 1&(2|3) 匹配同时包含 1 以及 2 或 3 的数组。

F.19.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.19.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.19.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.19.5. 作者 #

所有工作由 Teodor Sigaev () 与 Oleg Bartunov () 完成。更多信息请参阅 http://www.sai.msu.su/~megera/postgres/gist/。Andrey Oktyabrski 在添加新函数与操作方面做了出色的工作。