本文将系统性地讲解
psql的高效使用方法涵盖连接管理、元命令、SQL 执行、输出格式、变量与脚本、历史记录、配置优化、安全实践等多个维度旨在帮助读者真正“用好”这个看似简单却功能强大的命令行利器。
尽管图形化工具如 pgAdmin、DBeaver日益流行但 psql 凭借其轻量、高效、脚本友好、功能全面等优势在自动化运维、批量处理、远程调试和性能调优等场景中依然不可替代。更重要的是psql 深度集成 PostgreSQL 的所有特性能直接访问系统目录、执行元命令、控制事务行为甚至进行低延迟的交互式开发。
PostgreSQL 作为世界上最先进的开源关系型数据库系统其强大功能不仅体现在内核引擎上也体现在配套工具链中。其中psqlPostgreSQL interactive terminal作为官方提供的命令行客户端是每一位 PostgreSQL 用户——无论是开发者、DBA 还是数据分析师——都必须掌握的核心工具。
d, x, timing, pset 是日常高频命令.pgpass 和 .pg_service.confpsql -c 或 here document 实现自动化copy 与 COPY 的区别if, x auto。psql 不仅仅是一个“终端”它是通往 PostgreSQL 内核的桥梁。掌握其高级用法不仅能提升工作效率更能深入理解数据库的运行机制。正如一位资深 DBA 所言“当你能在 psql 中流畅完成所有操作时你才真正‘拥有’了你的数据库。”
| 类别 | 命令 |
|---|---|
| 连接 | psql -h host -U user -d db |
| 切换库 | c newdb |
| 查表结构 | d table |
| 扩展显示 | x |
| 显示时间 | timing |
| 导出 CSV | copy (SELECT ...) TO 'file.csv' CSV |
| 执行脚本 | i script.sql |
| 退出 | q |
psql 不仅是工具更是 PostgreSQL 世界的语言。
在大多数 Linux 发行版或 macOS通过 Homebrew中安装 PostgreSQL 会自动包含 psql。可通过以下命令验证
psql --version# 输出示例psql (PostgreSQL) 15.4
最常用的连接方式如下
psql -h host -p port -U username -d database
-h主机名或 IP默认为本地 Unix socket-p端口默认 5432-U用户名-d目标数据库名例如
psql -h localhost -p 5432 -U postgres -d myapp
若省略参数psql 会尝试使用当前系统用户名连接同名数据库通过 peer 或 ident 认证。
PostgreSQL 支持标准 URI 格式更简洁且便于脚本使用
psql "postgresql://user:password@localhost:5432/mydb?sslmode=disable"
注意密码明文出现在命令行可能被其他用户通过
ps查看生产环境应避免建议使用.pgpass文件见后文。
database_name=#超级用户或 database_name=>普通用户。q或按
Ctrl+D。psql 的一大特色是支持以反斜杠 开头的元命令Meta-Commands这些命令由 psql 本地解析不发送给服务器用于管理会话、查看元数据、控制输出等。
| 命令 | 作用 |
|---|---|
l[+] | 列出所有数据库+ 显示更多详情如大小、编码 |
c[onnect] [dbname] [username] | 切换数据库或用户 |
dt[+] [pattern] | 列出表支持通配符如 *, ? |
dv[+] | 列出视图 |
df[+] | 列出函数 |
di[+] | 列出索引 |
ds[+] | 列出序列 |
du[+] | 列出角色用户 |
dn[+] | 列出 schema |
示例
dt public.*_log -- 列出 public schema 中以 _log 结尾的表d+ users -- 查看 users 表的详细结构含注释、存储参数
| 命令 | 作用 |
|---|---|
e 或 edit | 打开外部编辑器编写 SQL默认 $EDITOR |
g | 执行当前缓冲区中的 SQL即使未以分号结尾 |
s [file] | 显示或保存 SQL 历史 |
watch [seconds] | 重复执行上一条查询类似 watch 命令 |
实用技巧
g 强制执行。e 在 Vim/VS Code 中编辑保存后自动执行。| 命令 | 作用 |
|---|---|
x | 切换“扩展显示模式”每列一行适合宽表 |
pset [option] [value] | 设置输出格式 |
a | 切换对齐/非对齐模式 |
t | 切换是否显示表头和行数 |
o [filename] | 将输出重定向到文件 |
H | 切换 HTML 输出模式 |
常用 pset 选项
pset null 'NULL'显式显示 NULL 值默认为空白pset pager off禁用分页适合脚本pset tuples_only on等价于 t仅输出数据pset format unaligned/csv/html设置输出格式示例导出 CSV
t onpset format csvo /tmp/users.csvSELECT * FROM users;ot off
psql 支持多行 SQL 输入直到遇到分号 ; 或 g 才执行
SELECT id, name, created_atFROM usersWHERE active = trueORDER BY created_at DESC;
若中途输错可按 Ctrl+C 清空当前缓冲区。
将常用操作保存为 .sql 文件通过 i 执行
i /path/to/init_db.sql
注意脚本中的错误默认不会中断执行如需严格模式可在脚本开头加
set ON_ERROR_STOP on
虽然 SQL 标准支持 BEGIN/COMMIT/ROLLBACK但 psql 也提供快捷方式
echo 'Starting transaction...'BEGIN; … COMMIT;set AUTOCOMMIT off 关闭。调试技巧在 set AUTOCOMMIT off 后可反复 ROLLBACK 测试 DML 操作而不污染数据。
psql 支持变量定义可用于动态 SQL 或避免硬编码。
set user_id 123set table_name 'orders'SELECT * FROM :table_name WHERE user_id = :user_id;
: 引用:'var' 自动加单引号。:DBNAME、:USER、:HOST 等自动包含当前连接信息:LASTOID上一条插入语句返回的 OID已弃用建议用 RETURNING:ERROR上一条命令是否出错用于脚本判断。通过 -v 参数传递变量
psql -v user_id=456 -v env=prod -f query.sql
在 query.sql 中
SELECT * FROM logs WHERE user_id = :user_id AND env = :'env';
注意
:'env'会自动转为'prod'防止 SQL 注入风险。
psql 自动保存历史到 ~/.psql_historyCtrl+R 反向搜索历史需 readline 支持。d 后按 Tab自动列出所有表SELECT * FROM u + Tab自动补全表名 users提示确保安装了
readline或libedit库以启用此功能。
| 快捷键 | 功能 |
|---|---|
Ctrl+A | 移动到行首 |
Ctrl+E | 移动到行尾 |
Ctrl+U | 删除整行 |
Ctrl+K | 删除从光标到行尾 |
Ctrl+L | 清屏 |
每次启动 psql 时会自动加载用户主目录下的 ~/.psqlrc 文件Windows 为 %APPDATA%postgresqlpsqlrc.conf。这是定制化体验的关键。
-- ~/.psqlrc-- 显示提示符用户名@数据库 时间>set PROMPT1 '%n@%/%x %`date +%H:%M:%S`> '-- 自动开启扩展显示可随时用 x 切换-- x auto -- PostgreSQL 15+ 支持自动模式-- 显式显示 NULLpset null '∅'-- 启用分页但脚本中可覆盖pset pager always-- 错误时停止脚本set ON_ERROR_STOP on-- 自动记录时间timing on-- 自定义快捷命令set whoami 'SELECT current_user, current_database(), inet_client_addr();'
可针对不同数据库设置不同行为
if :DBNAME = 'production' set PROMPT1 '33[1;31m%n@%/33[0m> ' -- 红色提示符警示else set PROMPT1 '%n@%/> 'endif
注意
if需 PostgreSQL 10+ 支持。
不要在命令行中写密码
# 危险psql -U admin -W -d mydb # 会提示输入但历史可能记录psql "user=admin password=secret dbname=mydb" # 更危险
正确做法使用 ~/.pgpass 文件
# ~/.pgpass 内容权限必须为 600hostname:port:database:username:password# 示例localhost:5432:mydb:admin:mypassword*:5432:*:deploy:deploypass
然后
chmod 600 ~/.pgpasspsql -h localhost -U admin -d mydb # 自动读取密码
对于多个环境dev/staging/prod可定义服务别名
# ~/.pg_service.conf[prod]host=prod-db.example.comport=5432user=appuserdbname=appdbsslmode=require[staging]host=staging-dbport=5432user=appuserdbname=appdb_staging
使用
psql service=prod
同样需设置权限
chmod 600 ~/.pg_service.conf
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM large_table WHERE id = 100;
配合 x 可清晰查看嵌套结构。
SELECT pid, usename, application_name, client_addr, state, query FROM pg_stat_activity WHERE state <> 'idle';
可用 watch 2 每2秒刷新一次。
pg_dump -U user --inserts --data-only -t users mydb > users.sql
copy users TO '/tmp/users.csv' WITH CSV HEADER;copy users FROM '/tmp/users.csv' WITH CSV HEADER;
注意
copy是psql命令文件路径相对于客户端而COPY是 SQL 命令路径相对于服务器。
创建一个每日备份脚本 backup.sh
#!/bin/bashDB=appdbDATE=$(date +%Y%m%d)psql -U backup -d $DB -v ON_ERROR_STOP=1 <<EOF o /backups/schema_$DATE.sql d+ o t on pset format csv o /backups/summary_$DATE.csv SELECT table_name, row_count FROM ( SELECT schemaname, tablename, n_tup_ins - n_tup_del AS row_count FROM pg_stat_user_tables ) t; oEOF
原因本地连接使用 peer 认证要求系统用户名 = 数据库用户名。
解决
-h localhost 强制走 TCP/IP触发 md5/password 认证pg_hba.conf将 local all all peer 改为 trust 或 md5重启生效。确保
UTF8建库时指定.psqlrc 中设置encoding UTF8
原因列宽过长psql 自动换行或截断。
解决
x 扩展模式pset columns 0 禁用自动折行。