postgresql 10 ltree 使用说明
官方文档 <a href='https://www.postgresql.org/docs/10/static/ltree.html' target=_blank'>https://www.postgresql.org/docs/10/static/ltree.html
ltree是俄罗斯Teodor Sigaev和Oleg Bartunov共同开发的PostgreSQL contrib扩展模块,它包含数据类型的实现、为树状结构组织的数据提供索引和查询。 http://www.sai.msu.su/~megera/postgres/gist/

关于GIST索引的一些介绍 https://yq.aliyun.com/articles/68244
一、安装ltree
CREATE EXTENSION IF NOT EXISTS ltree;
检查是否安装成功
select * from pg_extension where extname = 'ltree';

二、ltree的定义
- 标签是由一组字符数据(A-Za-z0-9_)组成的,每个标签最大256字节
- 标签的路径是由0个或多个点号分割(只能是.号),如 a.b.c.d
- 标签的总长度必须小于65kb,但最好维持在2kb以下
ltree提供两种数据类型
- ltree:存储标签路径
- lquery:表示用于匹配ltree值的类似正则表达式的模式。 一个简单的单词与路径中的标签匹配。 星号(*)匹配零个或多个标签。 例如:
foo 匹配确切的标签路径foo
*.foo.* 匹配包含标签foo的任何标签路径
*.foo 匹配最后一个标签为foo的任何标签路径
*标识可以量化,类似正则表达式
* {n}完全匹配n个标签
* {n,}匹配至少n个标签
* {n,m}匹配至少n个但不超过m个标签
* {,m}匹配最多m个标签 - 与* {0,m}相同
有几个修饰符可以放在lquery中非星形标签的末尾,以使其匹配的不仅仅是完全匹配:
@ 匹配大小写不敏感,例如@匹配A.
* 匹配任何带有此前缀的标签,例如foo *匹配foobar
% 匹配初始下划线分隔的单词
三、创建表&测试数据
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');
四、安装GIST和BTREE索引
CREATE INDEX path_gist_idx ON test USING gist(path);
CREATE INDEX path_idx ON test USING btree(path);
五、操作符
| 操作符 | 返回类型 | 描述 |
|---|---|---|
| tree @> ltree | boolean | 左参数是右边的祖先(或平等)? |
| tree <@ ltree | boolean | 左参数是右(或相等)的后代? |
| tree ~ lquery | boolean | ltree是否匹配lquery? |
| query ~ ltree | boolean | ltree是否匹配lquery? |
| tree ? lquery[] | boolean | ltree是否匹配数组中的任何lquery? |
| query[] ? ltree | boolean | ltree是否匹配数组中的任何lquery? |
| tree @ ltxtquery | boolean | ltree是否匹配ltxtquery? |
| txtquery @ ltree | boolean | ltree是否匹配ltxtquery? |
| tree | ltree | |
| tree | text | |
| ext | ltree | |
| tree[] @> ltree | boolean | 数组是否包含ltree的祖先? |
| tree <@ ltree[] | boolean | 数组是否包含ltree的祖先? |
| tree[] <@ ltree | boolean | 数组是否包含ltree的后代? |
| tree @> ltree[] | boolean | 数组是否包含ltree的后代? |
| tree[] ~ lquery | boolean | 数组包含任何匹配lquery的路径? |
| query ~ ltree[] | boolean | 数组包含任何匹配lquery的路径? |
| tree[] ? lquery[] | boolean | ltree数组是否包含任何匹配任何lquery的路径? |
| query[] ? ltree[] | boolean | ltree数组是否包含任何匹配任何lquery的路径? |
| tree[] @ ltxtquery | boolean | 数组包含任何匹配ltxtquery的路径? |
| txtquery @ ltree[] | boolean | 数组包含任何匹配ltxtquery的路径? |
| tree[] ?@> ltree | ltree | 第一个数组条目,是ltree的祖先;如果没有则为NULL |
| tree[] ?<@ ltree | ltree | 第一个数组条目,是ltree的后代;如果没有则为NULL |
| tree[] ?~ lquery | ltree | 第一个匹配lquery的数组条目;如果没有则为NULL |
| tree[] ?@ ltxtquery | ltree | 第一个匹配ltxtquery的数组条目;如果没有则为NULL |
六、ltree函数库及示例
执行结果部分全部都亲测过,可以参考下。
| 函数名 | 返回类型 | 描述 | 示例 | 执行结果 |
|---|---|---|---|---|
| subltree(ltree, int start, int end) | ltree | ltree寻找子路径,下标从start到end的 (从0开始计数),下标越界会出错 |
select subltree('a.b.c.d', -1,0); select subltree('a.b.c.d', 0,1); select subltree('a.b.c.d', 2,3); select subltree('a.b.c.d', 4,5); select subltree('a.b.c.d', 2,1) |
invalid positions a c invalid positions invalid positions |
| subpath(ltree, int offset, int len) | ltree | ltree根据偏移量offset和len寻找子路径, 如果offset为负则从路径末端开始。 如果len为负数,则将许多标签留在路径的末尾, ps:len为负数的最好少用,有点奇怪 |
select subpath('a.b.c.d', 0,2); select subpath('a.b.c.d', 0,9); select subpath('a.b.c.d', 1,2); select subpath('a.b.c.d', 4,1); select subpath('a.b.c.d', -1,1); select subpath('a.b.c.d', -1,2); select subpath('a.b.c.d', -2,1); select subpath('a.b.c.d', -2,2); select subpath('a.b.c.d', -2,9); select subpath('a.b.c.d', -3,2); |
a,b a,b,c,d b,c invalid positions d d c c,d c,d b,c |
| subpath(ltree, int offset) | ltree | ltree根据偏移量offset寻的子路径, 延伸到路径的末尾,如果offset为负, 则子路径从路径末端开始。 |
select subpath('a.b.c.d', 0); select subpath('a.b.c.d', 1); select subpath('a.b.c.d', 2); select subpath('a.b.c.d', 3); select subpath('a.b.c.d', 4); select subpath('a.b.c.d', -1); select subpath('a.b.c.d', -2); select subpath('a.b.c.d', -3); select subpath('a.b.c.d', -4); select subpath('a.b.c.d', -5); |
a,b,c,d b,c,d c,d d invalid positions d c,d b,c,d a,b,c,d d |
| nlevel(ltree) | integer | 计算路径中标签数量 | select nlevel(''); select nlevel('a'); select nlevel('a.b'); select nlevel('a.b.c.d'); |
0 1 2 4 |
| index(ltree a, ltree b) | integer | 计算第一次在a中出现b的位置, 没找到返回-1 |
select index('a.b.c.d','c.d'); select index('a.b.c.d','a'); select index('a.b.c.d','a,b'); select index('a.b.c.d','e'); |
2 0 0 -1 |
| index(ltree a, ltree b, int offset) | integer | 计算在a中第一次出现b的位置, 从偏移处开始搜索; 负偏移意味着从路径末端开始 |
select index('a.b.c.d.e','c.d',1); select index('a.b.c.d.e','c.d',2); select index('a.b.c.d.e','c.d',3); select index('a.b.c.d.e','c.d',-1); select index('a.b.c.d.e','c.d',-2); select index('a.b.c.d.e','c.d',-3); |
2 2 -1 -1 -1 2 |
| text2ltree(text) | ltree | text 转 ltree | ||
| ltree2text(ltree) | text | ltree 转 text | ||
| lca(ltree, ltree, ...) | ltree | 路径最长的公共前缀部分 (最多支持8个ltree参数) |
select lca('a.b.c.d','a.b.c'); select lca('a.b.c.d','a.b.c','a.b'); select lca('a.b.c.d','c.d'); |
a.b a '' |
| lca(ltree[]) | ltree | 路径最长的公共前缀部分 | lca(array['1.2.2.3'::ltree,'1.2.3']) | 1.2 |
七、查询实例
1.查找Top.Science开始的path
SELECT path FROM test WHERE path <@ 'Top.Science';
path
------------------------------------
Top.Science
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
(4 rows)
2.查找包含Astronomy的path
SELECT path FROM test WHERE path ~ '*.Astronomy.*';
path
-----------------------------------------------
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
Top.Collections.Pictures.Astronomy
Top.Collections.Pictures.Astronomy.Stars
Top.Collections.Pictures.Astronomy.Galaxies
Top.Collections.Pictures.Astronomy.Astronauts
(7 rows)
3.查找包含Astronomy且前面节点不含pictures的path
SELECT path FROM test WHERE path ~ '*.!pictures@.*.Astronomy.*';
path
------------------------------------
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
(3 rows)
4.查找第3个节点是'Astronomy'的,
注意此处最好加上nlevel(path) >2,因为可能有数据没有这么多节点
且where条件nlevel(path) >2要放在前面,postgresql的where条件是从前往后执行的
select path from test where nlevel(path) >2 and subpath(path,2,1) ='Astronomy';
path
------------------------------------
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
(3 rows)
错误示范:
select path from test where subpath(path,2,1) ='Science' and nlevel(path) >1;
select path from test where subpath(path,2,1) ='Science';
------------------------------------
ERROR: invalid positions
SQL state: 22023
5.查到第二个节点是Science,注意看nlevel的变量
select path from test where nlevel(path) >1 and subpath(path,1,1) ='Science' ;
------------------------------------
Top.Science
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
(4 rows)
select path from test where nlevel(path) >2 and subpath(path,1,1) ='Science' ;
------------------------------------
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
(3 rows)
基本的使用案例就到此,其他的自己可以多去试试。ltree还是非常适合省市县级联这种关系
postgresql 10 ltree 使用说明的更多相关文章
- PostgreSQL 10.7 linux 主从配置
PostgreSQL 10.7 主从安装 硬件环境 云服务商:华为云 Linux: CentOS7.1 工具:Xshell Xftp IP:114.115.251.168 Port: 5432 543 ...
- PostgreSQL 10 如何使用 PgAdmin3
自从 PgAdmin4 出来以后,PgAdmin3 就停止开发了,PgAdmin 官网下载的 PgAdmin3 无法支持 PostgreSQL 10 或者更高版本的数据库服务器端. 但是 PgAdmi ...
- [转帖] “王者对战”之 MySQL 8 vs PostgreSQL 10
原贴地址:https://www.oschina.net/translate/showdown-mysql-8-vs-postgresql-10?lang=chs&page=2# 英文原版地址 ...
- PostgreSQL 10首个测试版本发布
mysql 从5.7到8.0,pg从9.6到10,干起来了.. PostgreSQL 10 的首个测试版发布了,此版本包含 PostgreSQL 10 最终将提供的所有功能的预览.当然,有些细节将在最 ...
- CentOS 7 安装、配置、使用 PostgreSQL 10 安装及基础配置
官网安装方法:https://www.postgresql.org/download/linux/redhat/ 卸载的话使用 yum remove 相应的安装 Install the reposit ...
- “王者对战”之 MySQL 8 vs PostgreSQL 10
既然 MySQL 8 和 PostgreSQL 10 已经发布了,现在是时候回顾一下这两大开源关系型数据库是如何彼此竞争的. 在这些版本之前,人们普遍认为,Postgres 在功能集表现更出色,也因其 ...
- 在CentOS 7 / RHEL 7安装PostgreSQL 10
CentOS 到了7.x版本, PostgreSQL也来到了10.x版本. 前些天MySQL都直接跨到了8.0版本. 本文是一篇在CentOS 7.4上安装安装PostgreSQL 10.3 的教程. ...
- Ubuntu 18.04 下 PostgreSQL 10 的安装与基础配置
下载安装 在命令行执行如下语句: apt-get install postgresql-10 该指令会帮助你下载如下PostgreSQL组件: name |explain | ------------ ...
- 重磅发布!阿里云推PostgreSQL 10 高可用版
摘要: 近日,阿里云重磅发布PostgreSQL 10 高可用本地SSD盘版,相比原 9.4 版本又新增了JSONB.BRIN索引.GROUPING SETS/CUBE/ROLLUP.UPSERT等多 ...
随机推荐
- 【动态规划】bzoj1705: [Usaco2007 Nov]Telephone Wire 架设电话线
可能是一类dp的通用优化 Description 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务 于是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线. 新的电话线架设 ...
- paper:synthesizable finite state machine design techniques using the new systemverilog 3.0 enhancements 之 standard verilog FSM conding styles(二段式)
1.Two always block style with combinational outputs(Good Style) 对应的代码如下: 2段式总结: (1)the combinational ...
- python爬虫基础09-selenium大全3/8-Remote Webdriver
Selenium笔记(3)Remote Webdriver 本文集链接:https://www.jianshu.com/nb/25338984 简介 selenium.webdriver.remote ...
- manjaro18 配置国内镜像源
1.配置镜像源: sudo pacman-mirrors -i -c China -m rank 2.设置 archlinuxcn 源: sudo nano /etc/pacman.conf 添加以下 ...
- ubuntu 设置Path 开机启动脚本
vim /etc/rc.local export PATH=$PATH:/work/apps/node-v0.12.7-linux-x64/bin:/work/apps/ledisdb/binexpo ...
- meteor 检测运行环境,手机或者桌面
meteor add mystor:device-detection Meteor.Device.isPhone() https://atmospherejs.com/mystor/device-de ...
- BZOJ 3590: [Snoi2013]Quare
首先有一个性质,一个双联通图一定可以拆成一个小的双联通子图和一条链 一个点可以视为权值为0的双联通图或者一个点的链 状压DP,枚举子集 O(3^n*n^2) #include<cstdio> ...
- python socket相关
套接字的工作流程(基于TCP和 UDP两个协议) TCP和UDP对比 TCP(Transmission Control Protocol)可靠的.面向连接的协议(eg:打电话).传输效率低全双工通信( ...
- JavaScript日期时间格式化函数
这篇文章主要介绍了JavaScript日期时间格式化函数分享,需要的朋友可以参考下 这个函数经常用到,分享给大家. 函数代码: //格式化参数说明: //y:年,M:月,d:日,h:时,m分,s:秒, ...
- Oracle 了解 DDL 操作与 REDO 的关系
目录 了解 DDL 操作与 REDO 的关系 DDL是否会产生REDO 通过 10046 trace 来分析create 和drop 如果drop失败,redo的变化 了解 DDL 操作与 REDO ...