intarray

PostgreSQL 9.4.4 中文手册
上一页 | 上一级 | 附录 F. 额外提供的模块 | 下一页

# F.18. intarray

`intarray`模块为操作整数的null-free数组提供一些有用的函数和操作符。 也支持使用其中的一些操作符执行索引搜索。

如果提供的数组包含任何空元素，那么所有这些操作符都将抛出一个错误。

这些操作符中的一些只对一维数组敏感。尽管他们将接受多个维数的输入数组， 数据被按照存储的顺序当做一维数组。

## F.18.1. `intarray` 函数和操作符

`intarray`模块提供的函数显示在表 F-8里， 操作符显示在表 F-9里。

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

表 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 (`<teodor@sigaev.ru>`)和 Oleg Bartunov (`<oleg@sai.msu.su>`)完成的。参阅 http://www.sai.msu.su/~megera/postgres/gist/获取额外的信息。 Andrey Oktyabrski在添加新的函数和操作符上做了一个伟大的工作。

上一页 | 起始页 | 下一页
intagg | 上一级 | isn