数仓如何递归查询视图依赖
本文分享自华为云社区《GaussDB(DWS)如何递归查询视图依赖》,作者:半岛里有个小铁盒。
1. 前言
适用版本:【8.1.0(及以上)】
本文通过介绍with recursive递归查询的办法来实现查询视图的层级依赖关系
2. 实现简介
对于postgres生态来说,视图的依赖关系没有现成的查询方法,需要对系统表pg_depend及pg_rewrite编写复杂的组合查询才能得知,而对于Oracle和MySql,该需求都较易实现,分别查询USER_DEPENDENCIES和INFORMATION_SCHEMA.VIEWS即可轻易查出,因此在pg生态来说有必要编写一个直观的视图来查看各个视图与基表或与其他视图的层级依赖关系。本文通过with recursive递归查询的办法来实现视图的层级依赖关系查询。效果如下:
首先建立两个基表t1、t2,表结构随意,再建立一系列的视图进行层级关联,关联关系也随意。本文的建表及视图语句如下:
create table t1 (a int, b int) distribute by hash(a); create table t2 (a int, b int) distribute by hash(a); create view v1 as select * from t1; create view v2 as select * from v1; create view v3 as select * from v2; create view v4 as select * from v3; create view v5 as select * from t2; create view v6 as select * from v5; create view v7 as select * from v6; create view v8 as select * from v2;
实际的局点中,用户的视图依赖关系肯定要比这复杂得多,本文仅讲解原理。对于上述的视图依赖关系,可以通过如下查询得出:
SELECT c.ev_class::regclass::varchar AS objname, pc.oid::regclass::varchar AS refobjname, pc.relkind AS relkind FROM pg_depend a,pg_depend b,pg_class pc,pg_rewrite c WHERE a.refclassid=1259 AND a.classid=2618 AND b.deptype='i' AND a.objid=b.objid AND a.classid=b.classid AND a.refclassid=b.refclassid AND a.refobjid<>b.refobjid AND pc.oid=a.refobjid AND c.oid=b.objid AND (a.objid>=16384 or a.refobjid>=16384) GROUP BY c.ev_class,pc.oid,pc.relkind ORDER BY relkind;
其中倒数第二行的16384表示过滤掉系统对象,relkind表示上级依赖对象的类型,r说明依赖于基表,v表示依赖另一个视图。其查询结果如下:
可见这种查询并不直观,只能通过肉眼分析得出递归的依赖关系,对用户并不友好。莫急,先将上述查询保存为视图,例如起名为PUBLIC.gs_view_dependency。接下来我们来学习一下with recursive语法的使用方法,从pg官网可以get到的知识是,WITH语句通常被称为通用表表达式(Common Table Expressions)或者CTEs。WITH语句作为一个辅助语句依附于主语句,WITH语句和主语句都可以是SELECT,INSERT,UPDATE,DELETE中的任何一种语句。WITH语句还可以通过增加RECURSIVE修饰符来引入它自己,从而实现递归:
WITH RECURSIVE语句包含了两个部分:
- (非递归部分)non-recursive term,即上图中的union all前面的部分
- (递归部分)recursive term,即上图中union all后面的部分
执行步骤如下:
执行non-recursive term。(如果使用的是union而非union all,则需对结果去重)其结果作为recursive term中对result的引用,同时将这部分结果放入临时的working table中
重复执行如下步骤,直到working table为空:用working table的内容替换递归的自引用,执行recursive term,(如果使用union而非union all,去除重复数据),并用该结果(如果使用union而非union all,则是去重后的结果)替换working table
因此,照葫芦画瓢,我们可以先给这个CTE查询起个名字,例如:
WITH RECURSIVE get_view_dependency AS ( ... )
然后,我们可以把非递归部分写成:
SELECT a.objname, a.refobjname, a.refobjname path FROM PUBLIC.gs_view_dependency a where a.relkind = 'r'
因为查找到类型为’r’的基表的时候,递归就应该结束了。并且我们需要将refobjname组装成一条path来实现依赖路径的直观表示。因为是递归,所以我们需要不止一次的调用PUBLIC.gs_view_dependency,因此我们给它起个别名a。而递归的条件显而易见,应该是用refobjname来与objname做内关联,因此我们可以写作:
INNER JOIN get_view_dependency cte ON b.refobjname=cte.objname
其中cte就用来指代上一次的递归查询结果,而递归的退出条件就应该是最开始写的类型为’r’的情况。其中b就应该是递归部分每次调用的PUBLIC.gs_view_dependency。而我们除了要查询objname和refobjname外,更重要的是要组成一个path,而path每个节点最好通过一个’->'来直观表示,因此递归部分我们就可以写成:
SELECT b.objname, b.refobjname, cte.path ||' -> '|| b.refobjname path FROM PUBLIC.gs_view_dependency b INNER JOIN get_view_dependency cte ON b.refobjname=cte.objname
因此,整个CTE递归查询便可以写成:
WITH RECURSIVE get_view_dependency AS ( SELECT a.objname, a.refobjname, a.refobjname path FROM PUBLIC.gs_view_dependency a where a.relkind = 'r' UNION ALL SELECT b.objname, b.refobjname, cte.path ||' -> '|| b.refobjname path FROM PUBLIC.gs_view_dependency b INNER JOIN get_view_dependency cte ON b.refobjname=cte.objname ) SELECT * FROM get_view_dependency;
为了方便以后的使用,我们可以给它起个名字保存起来,例如CREATE VIEW PUBLIC.gs_view_table_dependency AS …。效果就是文章开头所示那样,便大功告成。
3. 总结
在数据库中,查询视图是一种非常有用的工具,它可以帮助我们更好地组织和管理数据。然而,查询视图的层级依赖关系可能会让人感到困惑。本文将介绍一种通过 with recursive 递归查询的办法来实现查询视图的层级依赖关系的方法,希望对你有所帮助。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
龙芯 LoongArch 架构在 Linux 6.8 内核初步支持 Rust
根据内核列表消息,龙芯 LoongArch 架构已在最新 Linux 6.8 版本中提供初步 Rust 支持。 https://lore.kernel.org/lkml/20240119110700.335741-1-chenhuacai@loongson.cn/T/#u Linux 6.8 内核和 LoongArch 架构相关的变化还包括将最低 Clang 编译器版本提升至 v18,为架构添加了内置 DTB 支持,并更新了默认内核配置文件。此外,补丁中还包含了一系列错误修复,以提升系统的稳定性和兼容性。 目前,Linux 6.8 内核的 LoongArch 相关 PR 已经被合并到主线 mainline。
- 下一篇
K8s集群CoreDNS监控告警最佳实践
本文分享自华为云社区《K8s集群CoreDNS监控告警最佳实践》,作者:可以交个朋友。 一 背景 coreDNS作为K8s集群中的关键组成部分。主要负责k8s集群中的服务发现,域名解析等功能。如果在使用过程中出现域名解析失败,域名解析超时等情况,需要引起注意。 二 方案简介 可以通过CCE集群插件kube-prometheus-stack进行coreDNS服务的指标监控,并提供开箱即用的仪表盘视图。时刻观察coreDNS的各项运行指标是否处于健康状态。 【加一下怎么到这个图的,选监控-仪表盘】 CCE普罗监控数据统一吐到华为云AOM2.0服务,可以在AOM2.0服务中根据展示各种普罗指标数据,并根据业务实际诉求,实现基于指标的的告警通知。 【CCE普罗对接哪个AOM实例】 【加一个AOM2.0图,可以看到AOM实例指标数据】 三 coreDNS关键指标 确保Prometheus已经成功抓取coreDNS相关指标 coreDNS请求速率:sum(rate(coredns_dns_requests_total{}[5m])) by (proto,instance) coreDNS请求速率...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2全家桶,快速入门学习开发网站教程
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- 2048小游戏-低调大师作品
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,CentOS7官方镜像安装Oracle11G