使用元数据

本页目录

当处理元数据 (关于数据的数据) 时,Postgres 中的这些参考文档非常有用:

没有必要重复文档中的内容。相反,我们专注于一些技巧和原则,使你的工作更高效。我们将讨论以下主题:


::oid,::regclass

在 Postgres 的术语中,表、索引、视图、物化视图均被称为"关系"。它们的元数据信息可以通过多种方式查看,但"核心"位置是 pg_class system catalog。换句话说,这是一个存储所有表、索引等信息的表。它有两个主键:

一个值得记住的技巧是:OID 可以快速转化为关系名,反之亦然,使用类型转换为 oid 和 regclass 数据类型。

以下是名为 t1 的表的简单示例:

PSQL
nik=# select 't1'::regclass;
 regclass
----------
 t1
(1 row)

nik=# select 't1'::regclass::oid;
  oid
-------
 74298
(1 row)

nik=# select 74298::regclass;
 regclass
----------
 t1
(1 row)

因此,不需要执行 select oid from pg_class where relname = ... — 只需记住 ::regclass 和 ::oid 即可。

? 和 ECHO_HIDDEN

psql 的 \? 命令非常重要 — 通过它可以找到所有命令的相关描述。例如:

SQL
\d[S+]                 list tables, views, and sequences

这些"描述"命令会隐式生成一些SQL语句 — "窥探"它们可能很有帮助。为此,我们首先需要开启 ECHO_HIDDEN:

PSQL
nik=# \set ECHO_HIDDEN on

或者在启动 psql 时使用 -E 选项。然后我们便可以开始窥探:

PSQL
nik=# \d t1
/********* QUERY **********/
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.~) '^(t1)$' COLLATE pg_catalog.default
 AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 2, 3;
/**************************/

[... + more queries to get info about "t1" ...]

查看这些查询可以帮助你构建各种处理元数据的工具。

性能

在某些情况下,元数据查询可能比较重且慢。如果出现这种情况,请考虑以下方法:

INFORMATION_SCHEMA

系统目录和视图是查询表和索引元数据的"本地"方式 — 但这并不是标准的方式。标准方法是 INFORMATION_SCHEMA,Postgres 根据 SQL 标准支持它:文档。如何使用:

pg_stat_activity 不是表

必须记住的是,在查询元数据时,你可能正在处理一些看起来像但行为不像普通表的东西。

例如,当你从 pg_stat_activity 中读取记录时,你并不是在处理一致的表数据快照:读取第一行和理论上的最后一行是在不同时刻产生的,你可能会看到并非同时运行的查询。

这种现象也解释了为什么 select now() - query_start from pg_stat_activity; 可能会给出负值:函数 now() 在事务开始时执行一次,并且在事务内部不会改变其值,无论调用它多少次。

要获取精确的时间间隔,请使用 clock_timestamp() 代替 (select clock_timestamp() - query_start from pg_stat_activity;)

讨论与补充

在 GitHub 查看讨论

支持作者

感谢支持 PostgreSQL Howto 的长期维护。

微信赞赏码

读者交流群

二维码若已过期,可通过公众号 PostgreSQL 学徒或邮件联系。

PostgreSQL 学徒读者交流群二维码