支持的版本:当前 (17) / 16 / 15 / 14 / 13
开发版本:开发版
不支持的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

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

intarray 模块为操作无空值的整数数组提供了一些有用的函数和运算符。它还支持使用某些运算符进行索引搜索。

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

这些操作中的许多仅适用于一维数组。尽管它们会接受更多维的输入数组,但数据被视为存储顺序中的线性数组。

此模块被认为是受信任的,即,拥有当前数据库 CREATE 权限的非超级用户可以安装它。

F.19.1. intarray 函数和运算符 #

intarray 模块提供的函数如表 F.8所示,运算符如表 F.9所示。

表 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}


表 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.19.2. 索引支持 #

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

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

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

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

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

GiST 和 GIN 索引之间的选择取决于 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 在添加新函数和操作方面做了大量工作。

提交更正

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