# F.21.树

F.21.1.定义F.21.2.运算符和函数F.21.3.索引F.21.4.实例F.21.5.转变F.21.6.作者

该模块实现了一种数据类型用于表示存储在层次树状结构中的数据标签。提供了广泛的设施,用于搜索标签树。

该模块被认为是“受信任的”,也就是说,它可以由拥有创造当前数据库的权限。

# F.21.1.定义

A.标签是字母数字字符和下划线的序列(例如,在C语言环境中A-Za-z0-9_允许)。标签长度必须小于256个字符。

例如:42,个人服务

A.标签路径例如,由点分隔的零个或多个标签序列L1.L2.L3,表示从层次树的根到特定节点的路径。标签路径的长度不能超过65535个标签。

例子:顶部国家。欧洲俄罗斯联邦

这个模块提供了几种数据类型:

  • 存储标签路径。

  • lquery表示用于匹配的类似正则表达式的模式价值观一个简单的单词与路径中的标签匹配。星象(*)匹配零个或多个标签。这些可以与点连接,形成必须与整个标签路径匹配的图案。例如:

    foo         Match the exact label path foo
    *.foo.*     Match any label path containing the label foo
    *.foo       Match any label path whose last label is foo
    

    星号和简单单词都可以量化,以限制它们可以匹配多少标签:

    *{n}        Match exactly n labels
    *{n,}       Match at least n labels
    *{n,m}      Match at least n but not more than m labels
    *{,m}       Match at most m labels — same as *{0,m}
    foo{n,m}    Match at least n but not more than m occurrences of foo
    foo{,}      Match any number of occurrences of foo, including zero
    

    在没有任何显式量词的情况下,星号的默认值是匹配任意数量的标签(即,{,})而非星形项的默认值是只匹配一次(即,{1}).

    有几个修饰符可以放在非星形的末尾lquery使其不只是精确匹配的项目:

    @           Match case-insensitively, for example a@ matches A
    *           Match any label with this prefix, for example foo* matches foobar
    %           Match initial underscore-separated words
    

    行为%这有点复杂。它试图匹配单词,而不是整个标签。例如富吧%比赛富巴兹但不是富奥·巴巴兹.如果与*例如,前缀匹配分别应用于每个单词富吧%*比赛foo1_bar2_baz但不是foo1_br2_baz.

    此外,您还可以编写几个可能已修改的非星形项,用|(或)匹配这些项目中的任何一项!(不)在非明星组的开始,匹配任何与任何备选方案不匹配的标签。一个量词,如果有的话,放在小组的末尾;这意味着整个组中有一定数量的匹配项(也就是说,有一定数量的标签匹配或不匹配任何替代项)。

    下面是一个注释示例lquery:

    Top.*{0,2}.sport*@.!football|tennis{1,}.Russ*|Spain
    a.  b.     c.      d.                   e.
    

    此查询将匹配以下任何标签路径:

    1. 从标签开始顶部

    2. next之前有零到两个标签

    3. 以不区分大小写前缀开头的标签运动

    4. 然后有一个或多个标签,但没有一个匹配足球运动也没有网球

    5. 然后以一个以罗斯还是完全匹配西班牙.

  • ltxtquery表示用于匹配的类似全文搜索的模式价值观一ltxtquery值包含单词,可能带有修饰符@, *, %最后;修饰语的含义与中的相同lquery.单词可以与&(以及),|(或),!(不是),以及括号。与lquery是吗ltxtquery匹配单词,而不考虑它们在标签路径中的位置。

    这里有一个例子ltxtquery:

    Europe & Russia*@ & !Transportation
    

    这将匹配包含标签的路径欧洲以及任何以俄罗斯联邦(不区分大小写),但不包括包含标签的路径运输.这些单词在路径中的位置并不重要。还有,什么时候%使用时,该单词可以与标签中任何下划线分隔的单词匹配,而不管其位置如何。

    注:ltxtquery允许符号之间使用空格,但lquery不要。

# F.21.2.运算符和函数

类型有常用的比较运算符=, <>, <, >, <=, >=.比较按树遍历的顺序排序,节点的子节点按标签文本排序。此外,中所示的专业操作员表F.13都有。

表F.13. 操作员

操作人员

描述
@> 布尔值

左派论点是右派(或同等)的祖先吗?
<@ 布尔值

左派论点是右派的后代吗?
~ lquery布尔值

lquery -是的。 LTREE公司→→布尔值

LTREE公司匹配L查询-是吗?
LTREE公司 -是吗? lquery[]→→布尔值

lquery[] -是吗? LTREE公司→→布尔值

LTREE公司匹配任何L查询在阵列中?
LTREE公司 -是的。 LTX查询→→布尔值

ltxt查询 @ ltree布尔值

ltree匹配ltxt查询?
ltree || ltreeltree

连接ltree路径。
ltree || 文本ltree

文本 || ltreeltree

将文本转换为ltree并连接。
ltree[] @> ltree布尔值

ltree <@ ltree[]布尔值

数组是否包含的祖先ltree?
ltree[] <@ ltree布尔值

ltree @> ltree[]布尔值

数组是否包含ltree?
ltree[] ~ 查询布尔值

查询 ~ ltree[]布尔值

数组是否包含任何路径匹配查询?
ltree[] ? 查询[]布尔值

查询[] ? ltree[]布尔值

ltree数组包含任何匹配任何路径查询?
ltree[] @ ltxt查询布尔值

ltxt查询 @ ltree[]布尔值

数组是否包含任何路径匹配ltxt查询?
ltree[] ?@> ltreeltree

返回第一个数组条目,它是ltree, 或者空值如果没有。
ltree[] ?<@ ltreeltree

返回第一个数组条目,它是ltree, 或者空值如果没有。
ltree[] ?~ 查询ltree

返回匹配的第一个数组条目查询, 或者空值如果没有。
ltree[] ?@ ltxt查询ltree

返回匹配的第一个数组条目ltxt查询, 或者空值如果没有。

运营商<@, @>, @~有类似物^<@,^@>,^@,^~,它们是相同的,只是它们不使用索引。这些仅用于测试目的。

可用功能显示在表 F.14.

表 F.14.ltree职能

功能

描述

例子)
子树(ltree,开始 整数,结尾 整数) →ltree

返回子路径ltree从位置*开始定位结尾*-1(从 0 开始计数)。

subltree('Top.Child1.Child2', 1, 2)孩子1
子路径(ltree,抵消 整数, 整数) →ltree

返回子路径ltree从位置开始*抵消, 有长度.如果抵消是负数,子路径从路径的末端开始。如果*是否定的,会在路径的尽头留下那么多标签。

subpath('Top.Child1.Child2', 0, 2)Top.Child1
子路径(ltree,抵消 整数) →ltree

返回子路径ltree从位置开始*抵消,延伸到路径的尽头。如果抵消*是负数,子路径从路径的末端开始。

子路径('Top.Child1.Child2',1)孩子1.孩子2
n级(ltree) →整数

返回路径中的标签数。

nlevel('Top.Child1.Child2')3
指数 ( 一种 ltree, b ltree ) → 整数

返回第一次出现的位置*b一种*, 或 -1 如果未找到。

指数('0.1.2.3.5.4.5.6.8.5.6.8','5.6')6
指数 ( 一种 ltree, b ltree,抵消 整数) →整数

返回第一次出现的位置*b一种, 或 -1 如果未找到。搜索从位置开始抵消;消极的抵消意味着开始-抵消*路径末端的标签。

指数('0.1.2.3.5.4.5.6.8.5.6.8','5.6',-4)9
text2ltree(文本) →ltree

演员表文本ltree.
ltree2text ( ltree ) → 文本

演员表ltree文本.
lca ( ltree[,ltree [, ... ]] ) → ltree

计算路径的最长共同祖先(最多支持 8 个参数)。

lca('1.2.3', '1.2.3.4.5.6')1.2
lca ( ltree[] ) → ltree

计算数组中路径的最长共同祖先。

lca(数组['1.2.3'::ltree,'1.2.3.4'])1.2

# F.21.3.索引

支持多种类型的索引,可以加速指定的运算符:

  • B-树索引:<,<=,=,>=,>

  • 要点索引结束(基本操作opclass):<,<=,=,>=, >, @>, <@, @, ~, ?

    基本操作GiST opclass将一组路径标签近似为位图签名。它的可选整数参数西格伦以字节为单位确定签名长度。默认签名长度为8字节。签名长度的有效值在1到2024字节之间。更长的签名会导致更精确的搜索(扫描更少的索引部分和更少的堆页),但代价是索引更大。

    创建默认签名长度为8字节的索引的示例:

    CREATE INDEX path_gist_idx ON test USING GIST (path);
    

    创建签名长度为100字节的索引的示例:

    CREATE INDEX path_gist_idx ON test USING GIST (path gist_ltree_ops(siglen=100));
    
  • 要点索引结束ltree[] (基本操作opclass):ltree[]<@ltree, ltree@>ltree[], @, ~, ?

    基本操作这个类的工作原理与基本操作并将签名长度作为参数。的默认值西格伦在里面基本操作是28字节。

    创建默认签名长度为28字节的索引的示例:

    CREATE INDEX path_gist_idx ON test USING GIST (array_path);
    

    创建签名长度为100字节的索引的示例:

    CREATE INDEX path_gist_idx ON test USING GIST (array_path gist__ltree_ops(siglen=100));
    

    注意:此索引类型是有损的。

# F.21.4.范例

本例使用以下数据(也可在文件中找到contrib/ltree/ltreetest。sql在源代码分发中):

CREATE TABLE test (path ltree);
INSERT INTO test VALUES ('Top');
INSERT INTO test VALUES ('Top.Science');
INSERT INTO test VALUES ('Top.Science.Astronomy');
INSERT INTO test VALUES ('Top.Science.Astronomy.Astrophysics');
INSERT INTO test VALUES ('Top.Science.Astronomy.Cosmology');
INSERT INTO test VALUES ('Top.Hobbies');
INSERT INTO test VALUES ('Top.Hobbies.Amateurs_Astronomy');
INSERT INTO test VALUES ('Top.Collections');
INSERT INTO test VALUES ('Top.Collections.Pictures');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Stars');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Galaxies');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Astronauts');
CREATE INDEX path_gist_idx ON test USING GIST (path);
CREATE INDEX path_idx ON test USING BTREE (path);

现在,我们有了一张桌子测验填充了描述如下所示层次结构的数据:

                        Top
                     /   |  \
             Science Hobbies Collections
                 /       |              \
        Astronomy   Amateurs_Astronomy Pictures
           /  \                            |
Astrophysics  Cosmology                Astronomy
                                        /  |    \
                                 Galaxies Stars Astronauts

我们可以这样做:

ltreetest=> SELECT path FROM test WHERE path <@ 'Top.Science';
                path
### F.21.5. Transforms

 Additional extensions are available that implement transforms for the `ltree` type for PL/Python. The extensions are called `ltree_plpythonu`, `ltree_plpython2u`, and `ltree_plpython3u` (see [Section 46.1](plpython-python23.html) for the PL/Python naming convention). If you install these transforms and specify them when creating a function, `ltree` values are mapped to Python lists. (The reverse is currently not supported, however.)

### Caution

 It is strongly recommended that the transform extensions be installed in the same schema as `ltree`. Otherwise there are installation-time security hazards if a transform extension's schema contains objects defined by a hostile user.

### F.21.6. Authors

 All work was done by Teodor Sigaev (`<[teodor@stack.net](mailto:teodor@stack.net)>`) and Oleg Bartunov (`<[oleg@sai.msu.su](mailto:oleg@sai.msu.su)>`). See [http://www.sai.msu.su/\~megera/postgres/gist/](http://www.sai.msu.su/~megera/postgres/gist/) for additional information. Authors would like to thank Eugeny Rodichev for helpful discussions. Comments and bug reports are welcome.