ITPub博客

首页 > 数据库 > > 从分析PG 一个\d 表名 而感到慌张

从分析PG 一个\d 表名 而感到慌张

作者:liuaustin 时间:2019-07-30 15:22:24 0 删除 编辑


学习一门技术或技巧,个人看伴随着几个阶段, 觉得简单或觉得很难的极端,这一般处于一个初级阶段,和每个人当时的拥有的知识水平不同有关,有的觉得很难,有的觉得很简单。

伴随着初级知识的掌握,就上升到第二个阶段,觉得什么都会和觉得哪里都不会的阶段,这也与每个人当前的知识水平和阅历有关。

而达到第三个阶段,就是觉得什么都不会的阶段。


在学习PG 的这段日子里面,越学习,越觉得哪里都不会,越学习,问题越多,越来越慌张。

PostgreSQL 其实能走到今天这样的火,不是偶然,只是一个人努力久了,终于等到了机会而已。最近在学习中,发现无论百度,还是 “国外百度”,都很少介绍PG的系统表,而大多都是简化的命令 \d  \dt  之类的,而这些命令其实都是由很多的系统表联合查询获得的。


下面从分析一个 \d  表名来看看有多少问题,执行 \d  表名的方式可以获得表结构的信息。

但执行的命令却需要 10个 语句来完成简单的显示,首先需要显示,表的OID 相当于这个表的OBJECT ID ,然后是这个表的schema 以及表明,这些信息通过 pg_class 和  pg_namespace 共同完成, 而pg_namespace 存储的是系统的schema 信息

SELECT c.oid,

  n.nspname,

  c.relname

FROM pg_catalog.pg_class c

     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace

WHERE c.relname OPERATOR(pg_catalog.~) '^(kong)$'

  AND pg_catalog.pg_table_is_visible(c.oid) ORDER BY 2, 3;


这段语句的重点是获得 oid


SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, c.relhasoids, '', c.reltablespace, CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, c.relpersistence, c.relreplident

test-# FROM pg_catalog.pg_class c

test-#  LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)

test-# WHERE c.oid = '25089';


在获得了OID 后,上面的语句会显示和这个数据表有关的一些属性 ,例如这个表是否有约束,是否带有索引,这个表到底是什么属性,是VIEW 还是其他,以及行是否添加了行级安全性等


SELECT a.attname,

  pg_catalog.format_type(a.atttypid, a.atttypmod),

  (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)

   FROM pg_catalog.pg_attrdef d

   WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),

  a.attnotnull,

  (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t

   WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS attcollation,

  a.attidentity

FROM pg_catalog.pg_attribute a

WHERE a.attrelid = '25089' AND a.attnum > 0 AND NOT a.attisdropped

ORDER BY a.attnum;


核心的表结构的信息显示就在这条语句,表列的信息都存储在pg_catalog.pg_attribute,在表pg_attribute 中包含了所有表的column信息,通过这条语句将和这个所要查的表的列信息都打印出来


SELECT inhparent::pg_catalog.regclass,

  pg_catalog.pg_get_expr(c.relpartbound, inhrelid)

FROM pg_catalog.pg_class c JOIN pg_catalog.pg_inherits i ON c.oid = inhrelid

WHERE c.oid = '25089' AND c.relispartition;

上面这条语句就是显示这个表是否有继承的关系


SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),

  pg_catalog.pg_get_constraintdef(con.oid, true), contype, condeferrable, condeferred, i.indisreplident, c2.reltablespace

FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i

  LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))

WHERE c.oid = '25089' AND c.oid = i.indrelid AND i.indexrelid = c2.oid

ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;

上边这条语句是展示,系统中的通过这条语句可以查询出表中所有索引的建立的语句


SELECT pol.polname, pol.polpermissive,

  CASE WHEN pol.polroles = '{0}' THEN NULL ELSE pg_catalog.array_to_string(array(select rolname from pg_catalog.pg_roles where oid = any (pol.polroles) order by 1),',') END,

  pg_catalog.pg_get_expr(pol.polqual, pol.polrelid),

  pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid),

  CASE pol.polcmd

    WHEN 'r' THEN 'SELECT'

    WHEN 'a' THEN 'INSERT'

    WHEN 'w' THEN 'UPDATE'

    WHEN 'd' THEN 'DELETE'

    END AS cmd

FROM pg_catalog.pg_policy pol

WHERE pol.polrelid = '25089' ORDER BY 1;

上面的语句是展示关于表的行级安全策略,具体什么是行级安全?


SELECT pubname

FROM pg_catalog.pg_publication p

JOIN pg_catalog.pg_publication_rel pr ON p.oid = pr.prpubid

WHERE pr.prrelid = '25089'

UNION ALL

SELECT pubname

FROM pg_catalog.pg_publication p

WHERE p.puballtables AND pg_catalog.pg_relation_is_publishable('25089')

ORDER BY 1;


下面这条语句是查询PG 的这张表是否进行了发布


剩下还有4个语句实在不知道作用是什么也就不贴了


从分析这一条 \d 表名总结出以下问题

1  涉及这次查询的的系统表的功能和里面可以展示的信息,你都理解和领会了吗

2 PG 涉及了表继承的知识,你知道吗

3 PG 里面的函数高深莫测,一个函数可以通过索引的ID 将索引创建的语句进行展示,到底PG 里面还有多少这样的函数

4  行级策略是什么

5  PG 支持表级别的发布订阅


通过一个\d  表名 我找到若干的问题,当然有些问题可能不重要,或者你不理解也不会影响你使用PG,但问题是,还有多少需要知道和关键的信息不知道,所以想到这,就开始慌张了。


原文作者:;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2018-11-13

  • 博文量
    1980
  • 访问量
    522783