F.18. intarray
intarray
模块为操作整数的null-free数组提供一些有用的函数和操作符。 也支持使用其中的一些操作符执行索引搜索。
如果提供的数组包含任何空元素,那么所有这些操作符都将抛出一个错误。
这些操作符中的一些只对一维数组敏感。尽管他们将接受多个维数的输入数组, 数据被按照存储的顺序当做一维数组。
F.18.1. intarray
函数和操作符
intarray
模块提供的函数显示在Table F-8里, 操作符显示在Table F-9里。
Table F-8. intarray
函数
函数 | 返回类型 | 描述 | 示例 | 结果 |
---|---|---|---|---|
icount(int[]) |
int |
数组中元素的个数 | icount('{1,2,3}'::int[]) |
3 |
sort(int[], text dir) |
int[] |
给数组排序 — dir 必须为 asc 或 desc |
sort('{1,2,3}'::int[], 'desc') |
{3,2,1} |
sort(int[]) |
int[] |
以升序顺序排序 | sort(array[11,77,44]) |
{11,44,77} |
sort_asc(int[]) |
int[] |
以升序顺序排序 | ||
sort_desc(int[]) |
int[] |
以降序顺序排序 | ||
uniq(int[]) |
int[] |
删除相邻的重复 | uniq(sort('{1,2,3,2,1}'::int[])) |
{1,2,3} |
idx(int[], int item) |
int |
匹配item 的第一个元素中的索引 (如果没有则为0) |
idx(array[11,22,33,22,11], 22) |
2 |
subarray(int[], int start, int len) |
int[] |
在 start 位置开始的, len 个元素的数组的一部分 |
subarray('{1,2,3,2,1}'::int[], 2, 3) |
{2,3,2} |
subarray(int[], int start) |
int[] |
在 start 位置开始的数组的一部分 |
subarray('{1,2,3,2,1}'::int[], 2) |
{2,3,2,1} |
intset(int) |
int[] |
制作单个元素的数组 | intset(42) |
{42} |
Table F-9. intarray
操作符
操作符 | 返回 | 描述 |
---|---|---|
int[] && int[] |
boolean |
重复 — 如果数组至少有一个共同元素则为true |
int[] @> int[] |
boolean |
包含 — 如果左边的数组包含右边的数组则为true |
int[] <@ int[] |
boolean |
包含于 — 如果左边的数组包含于右边的数组则为true |
# int[] |
int |
数组中元素的个数 |
int[] # int |
int |
索引 (和idx 函数相同) |
int[] + int |
int[] |
将元素推入数组中(将元素添加到数组的末尾) |
int[] + int[] |
int[] |
数组串联(右边的数组添加到左边的数组的后面) |
int[] - int |
int[] |
删除匹配右边数组中元素的项 |
int[] - int[] |
int[] |
从左边数组中删除右边数组中的元素 |
int[] | int |
int[] |
参数的并集 |
int[] | int[] |
int[] |
数组的并集 |
int[] & int[] |
int[] |
数组的交集 |
int[] @@ query_int |
boolean |
如果数组满足查询则为true (见下文) |
query_int ~~ int[] |
boolean |
如果数组满足查询则为true (@@ 的交换子) |
(PostgreSQL 8.2之前,包含操作符@>
和<@
分别称为@
和 ~
。这些名字仍然可以使用,但是已经废弃了并且最终会被撤销。 请注意,旧的名字从大会移除,之前跟随着核心几何数据类型!)
操作符&&
, @>
和 <@
等同于 PostgreSQL同名的内建操作符,除了它们只工作于整数数组不包含空值, 而内建操作符工作于任意数组类型。这个限制使它们在任何情况下都比内建操作符快的多。
@@
和 ~~
操作符测试一个数组是否满足一个query, 该查询表示为一个专门的数据类型query_int
的值。query 由针对数组元素检查的整数值组成,可能混合使用操作符&
(与), |
(或), 和 !
(非)。在需要时可以使用括号。 例如,查询1&(2|3)
匹配包含1也包含2或3的数组。
F.18.2. 索引支持
intarray
为&&
, @>
, <@
, 和 @@
操作符还有普通数组相等提供索引支持,
提供两个GiST索引操作符类:gist__int_ops
(缺省使用) 适合于小到中等的数据集,而gist__intbig_ops
使用一个大的签名并且更适合于索引大的数据集(也就是, 包含大量不同数组值的字段)。该实现使用一个RD树数据结构和内建的有损压缩。
还有一个非缺省的GIN操作符类gin__int_ops
支持相同的操作符。
GiST和GIN索引的选择取决于GiST和GIN相关的性能特性,这个在别的地方讨论。 一般来说,GIN索引比GiST索引搜索起来更快一些,而建立或更新要慢一些; 所以GIN更适合于静态数据,而GiST更适合于经常更新的数据。
F.18.3. 示例
-- 一个message可以在一个或多个"sections"中
CREATE TABLE message (mid INT PRIMARY KEY, sections INT[], ...);
-- 创建专门的索引
CREATE INDEX message_rdtree_idx ON message USING GIST (sections gist__int_ops);
-- 在section 1或2中选择message -OVERLAP操作符
SELECT message.mid FROM message WHERE message.sections && '{1,2}';
-- 在section 1和2中选择message -CONTAINS操作符
SELECT message.mid FROM message WHERE message.sections @> '{1,2}';
-- 相同的,使用QUERY操作符
SELECT message.mid FROM message WHERE message.sections @@ '1&2'::query_int;
F.18.4. 基准
源目录contrib/intarray/bench
包含一个基准测试套件。运行:
cd .../bench
createdb TEST
psql TEST < ../_int.sql
./create_test.pl | psql TEST
./bench.pl
bench.pl
脚本有许多选项,当它不带任何参数的运行时显示。
F.18.5. 作者
所有工作都是Teodor Sigaev (<[[email protected]](mailto:[email protected])>
)和 Oleg Bartunov (<[[email protected]](mailto:[email protected])>
)完成的。参阅 http://www.sai.msu.su/~megera/postgres/gist/获取额外的信息。 Andrey Oktyabrski在添加新的函数和操作符上做了一个伟大的工作。