pg查询表所拥有的子表

业务需求:

1.有两个schema 分别为a,b

2.schema a下有一张表,叫做a;schema b下有一张表,叫做b,b继承于a,即b为a的子表;其中表b.b可能存在,也可能不存在

在schema a进行删除前,需要判断它的表a是否存在与它不在同一个schema内的子表;如果子表存在,则父表不进行删除

可以清晰的看到,业务的难点,就是要得到schema a下的表a,它所拥有的子表schema名称和表名。

要完成以上业务需求,需要查询pg系统表。

由于子表使用inherits语法实现的,所以我们首先了解下pg_inherits表:


可以看到,pg_inherits表存了父表的oid和子表的oid

oid该如何得到呢?我们需要了解pg_class表

pg_class表里有relname表示表名,那么表所在的schema又如何确定呢?


可以清晰看到,就是用pg_namespace表的oid与pg_class表的relnamespace进行关联,并且用pg_namespace表的namespace过滤指定schema名称即可。


综上所述,通过以上三张表,我们可以完成期待完成的业务。


1.使用pg_namespace,pg_inherits,pg_class三张表关联,我们可以得到schema a的表a的子表名称及schema oid

select relname,relnamespace
from
(
select inhrelid from 
pg_namespace,pg_class,pg_inherits 
where pg_namespace.oid=pg_class.relnamespace and pg_namespace.nspname='a' and relname='a' and pg_class.oid=pg_inherits.inhparent
) a,pg_class b
where a.inhrelid=b.oid


2.我们把上一步的sql作为嵌套子查询,即可以得到schema a的表a的子表的schema名称以及表名:

select relname as tablename,nspname as schemaname
from
(
select relname,relnamespace
from
(
select inhrelid from 
pg_namespace,pg_class,pg_inherits 
where pg_namespace.oid=pg_class.relnamespace and pg_namespace.nspname='a' and relname='a' and pg_class.oid=pg_inherits.inhparent
) a,pg_class b
where a.inhrelid=b.oid
) c,pg_namespace
where c.relnamespace=pg_namespace.oid;

结果如下图所示:



### 查看PostgreSQL中的表分区 在 PostgreSQL 中,可以通过多种方式来查看表的分区情况。对于继承式分区(传统方法),可以利用 `pg_inherits` 系统目录以及查询特定模式下的所有子表。 #### 方法一:通过 pg_inherits 和 information_schema.tables 为了获取父级分区表及其对应的子分区列表,可执行如下 SQL 查询: ```sql SELECT concat('Parent Table: ', p.tablename, E'\n') || string_agg(concat('Partition: ', c.relname), E',\n') FROM pg_class c JOIN pg_inherits i ON c.oid = i.inhrelid JOIN pg_class pc ON i.inhparent = pc.oid JOIN pg_tables p ON pc.relname = p.tablename WHERE c.relkind = 'r' AND p.schemaname NOT IN ('pg_catalog', 'information_schema') GROUP BY p.tablename; ``` 此脚本会返回每个作为父类存在的表格名称连同它所拥有的各个分片的名字[^1]。 #### 方法二:针对声明式分区 (Declarative Partitioning) 自版本 10 起引入了更简便的方式定义和管理范围、列表类型的分区结构。要检查这些现代风格下创建出来的对象,则应该查阅 `pg_partitioned_table` 及关联视图。 下面是一条适用于此类情形的命令: ```sql SELECT partition_strategy, string_agg(partition_key::text, ',' ORDER BY subpartition_level) AS keys FROM ( SELECT DISTINCT pt.partition_strategy, unnest(pg_get_expr(def.adbin, def.adrelid)::text[]) as partition_key, row_number() OVER () % 2 AS subpartition_level FROM pg_attribute att JOIN pg_attrdef def ON att.attnum = def.adnum AND att.attrelid = def.adrelid JOIN pg_partitioned_table pt ON att.attrelid = pt.partrelid WHERE att.atthasdef IS TRUE AND att.attisdropped IS FALSE AND format_type(atttypid, atttypmod) LIKE '%partition%' ) t GROUP BY partition_strategy; ``` 上述语句能够展示关于给定数据库内已知分区策略的信息,并指出用于划分数据的关键字段。 另外,在日常开发维护过程中如果仅需简单确认某张表是否为分区表,可以直接尝试运行 `\d+ 表名` 命令于psql客户端工具之中;这将提供有关该实体更为详尽的数据字典描述,其中便包含了其所属类别——即常规表还是某种形式上的分区体。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值