如何在PostgreSQL中列出不含子分区的所有主表
如何在PostgreSQL指定模式中仅列出分区主表(排除子分区)
你提到的问题很常见——依赖表名中的特定字符串过滤分区确实不可靠,毕竟命名规则可能随时改变。PostgreSQL的系统元数据里已经提供了原生的区分方式,完全不需要靠猜表名。
这里有两种可靠的实现方法,你可以根据需求选择:
方法一:使用系统目录表(高效推荐)
PostgreSQL的pg_class表存储了所有关系(包括表)的元数据,其中relispartition字段可以直接判断一个表是不是子分区(true表示是子分区),relhassubpartition字段则标记该表是否有子分区(true表示是分区主表)。结合pg_namespace来指定模式,查询语句如下:
SELECT n.nspname AS schema_name, c.relname AS table_name FROM pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid WHERE n.nspname = '你的模式名' -- 替换成你要查询的模式 AND c.relkind = 'r' -- 只筛选普通表(排除视图、序列等) AND c.relispartition = false -- 排除子分区表 AND c.relhassubpartition = true; -- 只保留有子分区的主表(即分区主表)
如果你的需求是排除所有子分区,保留普通表+分区主表,只需要去掉最后一行AND c.relhassubpartition = true即可。
方法二:结合information_schema和系统表
如果你更习惯用information_schema,可以关联pg_inherits来排除子分区表。子分区表会作为继承表出现在pg_inherits的inhrelid字段中,所以我们可以筛选不在这个列表里的表,同时确保是分区主表:
SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema = '你的模式名' -- 替换成目标模式 AND table_type = 'BASE TABLE' AND (table_schema, table_name) NOT IN ( SELECT n.nspname, c.relname FROM pg_inherits i JOIN pg_class c ON i.inhrelid = c.oid JOIN pg_namespace n ON c.relnamespace = n.oid ) AND EXISTS ( -- 确保该表有子分区(即它是分区主表) SELECT 1 FROM pg_inherits i JOIN pg_class c ON i.inhparent = c.oid JOIN pg_namespace n ON c.relnamespace = n.oid WHERE n.nspname = table_schema AND c.relname = table_name );
同样,如果不需要只保留分区主表,去掉最后的EXISTS子句即可。
这两种方法都完全不依赖表名规则,直接利用PostgreSQL的原生元数据,可靠性拉满。
内容的提问来源于stack exchange,提问作者quarague
相关产品推荐
相关产品推荐

