# psql 基础

> 运行 SQL 文件，以交互方式探索数据库，并获取 psql 的帮助。

---

LLMS 索引： [llms.txt](/llms.txt)

---

`psql` 是 PostgreSQL 官方的命令行客户端，非常好用。大多数专业用户都会优先使用它，而不是图形界面工具：它速度快，支持脚本，而且每次安装 PostgreSQL 都会附带。它有两种用法：以批处理模式（`psql -f file.sql`）运行脚本，或者进入交互模式（`psql`），逐条输入 SQL 和元命令。本章介绍基础用法；后面的章节会介绍更多元命令。

## 本章要点 {#learn}

- `psql` 的两种模式：文件模式与交互模式
- 如何确认当前会话的身份与环境（当前用户、数据库、模式）
- SQL 语句与 `psql` 元命令的区别
- 如何获取帮助：用 `\?` 查看元命令帮助，用 `\h` 查看 SQL 帮助

## 示例 {#example}

```sql {num="2.1" caption="psql 基础"}
-- List user databases. Equivalent to \l in interactive psql.
SELECT datname
FROM pg_database
WHERE datistemplate = false
ORDER BY datname
LIMIT 5;

-- Identify the session: who am I, where am I, what's on my search_path?
SELECT current_user, current_database(), current_schema();

-- A few server settings worth knowing about
SHOW timezone;
SHOW server_encoding;
```

`pg_database` 是众多*系统目录*之一，也就是 PostgreSQL 提供给用户查看的内部表。`datistemplate = false` 这个过滤条件会隐藏 `template0` 和 `template1`，新数据库都是从这两个模板克隆而来的。`current_user`、`current_database()` 和 `current_schema()` 是会话函数；排查连接或权限问题时，你经常会需要它们提供的信息。`SHOW` 显示运行时参数，这些参数可以在服务器、数据库、角色或会话级别修改。

交互式使用 `psql` 时，还可以输入由客户端在本地解释的**元命令**（也称*反斜线命令*）：

```text
\l         list databases
\c db      connect to database `db`
\dt        list visible tables in the current search_path
\d table   describe a table (columns, types, indexes)
\dn        list schemas
\df        list functions
\du        list roles (users/groups)
\timing    toggle showing query timing
\x         toggle expanded display (great for wide rows)
\?         help for meta-commands
\h SELECT  help for the SELECT command (or any SQL keyword)
\q         quit
```

无论是在交互模式中，还是在通过 `psql -f` 读取的文件中，元命令都由 `psql` 客户端解释。`\dt` 等命令会向服务器发送系统目录查询；反斜线语法本身并不是服务器端的 SQL。

## 运行示例 {#run}

运行这个文件：

```text
$ psql -f source/psql-basics.sql postgres
       datname
--------------------
 postgres
(1 row)

 current_user | current_database | current_schema
--------------+------------------+----------------
 your_user    | postgres         | public
(1 row)

 TimeZone
----------
 UTC
(1 row)

 server_encoding
-----------------
 UTF8
(1 row)
```

## 常见陷阱 {#pitfalls}

- 元命令需要 psql 客户端。`psql -f` 可以执行文件中的 `\dt`；如果驱动或图形界面工具直接把文件作为 SQL 发送，就不会解释这个命令。
- 混淆 `current_user` 与 `session_user`：当 `SET ROLE` 生效时，`current_user` 反映当前生效的角色，而 `session_user` 仍是最初登录的用户。
- 编码不匹配：如果终端不是 UTF-8 编码，而数据库是，就可能出现乱码。将 `client_encoding` 设为与终端一致的编码。

> [!TIP] 提示
> 将 `\set PROMPT1 '%n@%/%x%R%# '` 加入 `~/.psqlrc`，让提示符显示用户、数据库和事务状态。用 `\e` 在 `$EDITOR` 指定的编辑器中编辑上一条查询。调优查询时，可用 `\timing on` 开启计时。

> [!NOTE] 动手练习
> 用 `psql postgres` 启动交互式会话，依次运行 `\l`、`\dt`、`\d pg_database`，最后用 `\q` 退出。用 `\dt pg_catalog.*` 比较不同模式下 `\dt` 显示的内容。

## 下载 {#downloads}

SQL 文件： [psql-basics.sql](/examples/source/psql-basics.sql) · [全部示例文件](/examples/examples.zip) · [准备工作](/#prerequisites)
