HOWTO · PostgreSQL

如何列出 PostgreSQL 中的所有表

通过查询 INFORMATION_SCHEMA 视图或使用 psql 的表列表元命令,并按 schema 过滤结果,列出 PostgreSQL 数据库中的所有表。

本页内容

查看 PostgreSQL 数据库中所有表的最快方法,是查询 information_schema.tables 视图,或者在 psql 中运行 \dt 元命令。下面依次介绍这两种方式。

INFORMATION_SCHEMA 是每个 PostgreSQL 数据库中自动存在的一个 schema。它通过 SQL 标准定义的一组视图暴露数据库对象的元数据,因此 information_schema.tables 本身是一个描述表和视图的视图,而不是存储用户数据的表。查询它可以告诉你哪些对象存在、每个对象属于哪个 schema;但它不会赋予你这些对象上诸如 DROP 之类的权限。权限仍然来自 GRANT,而这些视图只报告当前角色被允许看到的对象。

本文中的语句都是普通的 SQL 和 psql 命令,供你在自己的数据库会话中运行,因此以可复制的语法形式展示,而不是附带捕获的输出。

使用 information_schema.tables 列出所有表

要列出数据库已知的所有表类对象,运行:

SELECT * FROM information_schema.tables;

返回的每一行描述一个对象。常用的列有 table_catalog(数据库名)、table_schema(对象所在的 schema)、table_name 和 table_type(普通表为 BASE TABLE,视图为 VIEW)。如果只需要名称,可以只投影较少的列:

SELECT table_schema, table_name FROM information_schema.tables;

下面是结果大致样子的简化示例(列名和取值与实际查询输出一致,保持英文原样):

table_catalog table_schema table_name table_type
postgres public customers BASE TABLE
postgres information_schema tables VIEW

注意,一条查询会返回来自多个 schema 的行。table_schema 列告诉你每个对象属于哪个 schema,所以 public、pg_catalog 和 information_schema 的行会并排出现。由于 INFORMATION_SCHEMA 遵循 SQL 标准(ISO/IEC 9075),同样的查询也适用于其他数据库系统,而 pg_catalog 保存的是 PostgreSQL 自己的系统目录表。

按 schema 过滤表

在 table_schema 上添加 WHERE 子句,可以把结果缩小到单个 schema。应用表通常位于 public 中:

SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';

把它替换成你需要的任意 schema 即可。例如,WHERE table_schema = 'information_schema' 会列出标准视图本身,'pg_catalog' 则列出系统目录。由于 information_schema.tables 也会报告视图,当你只要真正的表时,再加上一个 table_type 条件:

SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE';

使用 psql 列出表

在 psql 交互式终端中,\dt 元命令会打印一份紧凑的表清单。不带参数的 \dt 显示 search_path 上各 schema 中的表,通常只有 public。要明确指定某个 schema,给模式加上限定:

\dt public.*

要一次查看所有 schema 中的表,两部分都使用通配符:

\dt *.*

结果是一张标题为 List of relations 的表格,包含 Schema、Name、Type 和 Owner 列(这些列名是 psql 的实际输出标签,保持英文原样):

Schema Name Type Owner
public customers table postgres

有两点限制需要记住。\dt 只列出表,因此不会显示 INFORMATION_SCHEMA 的内容——那些都是视图:查看视图用 \dv information_schema.*,要列出该 schema 中所有类型的关系则用 \d information_schema.*。另外,这些元命令只能在 psql 内部使用;它们不是可以通过其他客户端或驱动程序发送的 SQL 语句。

理解 schema 与相关的 psql 命令

schema 是数据库内部的命名空间,因此不同的 schema 可以包含同名的表。这就是为什么不过滤的列表会把多个 schema 的行混在一起,也是为什么阅读结果时 table_schema 或 Schema 列很重要。

看起来相似的命令做的其实是不同的事,值得分清楚:

  • \dt 列出表,而 \dv 列出视图。
  • \dn 列出的是 schema(命名空间)本身。\dn information_schema 显示该 schema 的条目,包括其所有者——它并不列出表。
  • \z 等价于 \dp,打印每个对象上授予的访问权限。它适合用来审计权限,而不是列出表。注意要用反斜杠书写;输入正斜杠的 /z 会报错。

从这些区别可以得出一个实用的工作流程:用 information_schema.tables 或 \dt 枚举表,加上 table_schema 过滤条件或 schema 模式来缩小范围;当你需要的是 schema 或权限方面的细节而不是表清单时,再使用 \dn 或 \z。