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。