根本原因是客户端与服务端编码不一致,Navicat需强制设为UTF-8解码;服务端须为UTF8编码;应用连接须显式指定client_encoding=utf8;导出导入SQL文件必须统一用UTF-8编码。
Navicat 连接 PostgreSQL 时中文显示为问号或方块
根本原因是客户端编码与数据库服务端编码不一致,navicat 默认用系统 locale(比如 windows 的 gbk)去解码 postgresql 返回的 utf-8 字节流,一解就错。
实操上必须让 Navicat 明确以 UTF-8 解析通信内容,而不是依赖系统设置:
- 连接建立前,在 Navicat「连接属性 → 高级」里勾选
Use Unicode UTF-8 for all connections - 连接已存在?右键编辑连接 → 「高级」→ 勾选同上选项 → 点击「测试连接」确认生效
- 如果仍乱码,检查 PostgreSQL 服务端是否真在用 UTF-8:连上去执行
SHOW SERVER_ENCODING;,结果必须是UTF8;不是的话,初始化集群时就得指定-E UTF8,运行中无法更改
INSERT 中文数据后查出来是乱码,但 Navicat 自己写入正常
说明问题不在 Navicat 显示层,而在应用代码或 SQL 客户端发来的原始字节没按 UTF-8 编码。
常见于 Python、Java 等程序直连 PostgreSQL 时忽略连接参数:
- Python psycopg2:创建连接时必须显式传
client_encoding='utf8',否则默认用操作系统 locale(Windows 下常是GBK) - Java JDBC:URL 后加
?currentSchema=public&characterEncoding=utf-8(注意是characterEncoding,不是charset) - psql 命令行:启动前设环境变量
PGCLIENTENCODING=utf8,否则可能继承终端编码(如 macOS Terminal 是 UTF-8,Windows cmd 默认是 GBK)
Navicat 的「自动提交」和「手动提交」对中文事务有影响吗
没有直接关系。乱码和事务模式无关,但容易混淆——因为手动提交时,你可能在未提交的事务里 INSERT 中文,然后换另一个工具(比如 psql)去查,看到的是旧快照或报错,误以为是编码问题。
排查时先排除干扰:
- 确保所有查询都在同一连接、同一事务上下文中观察
- Navicat 执行完 INSERT 后,点「提交」按钮(或 Ctrl+S),再刷新数据表视图
- 如果用「查询」窗口执行语句,注意窗口右下角状态栏是否显示
Auto-commit: ON;关了就要自己敲COMMIT;
Navicat 导出 SQL 文件含中文,再导入时报错或乱码
导出时若没指定编码,Navicat 默认用系统编码保存 .sql 文件(Windows 下是 ANSI/GBK),而 psql -f xxx.sql 默认按 UTF-8 读——字节对不上,必然出错。
安全做法只有两种:
- 导出时在「导出向导」最后一步,明确选择编码为
UTF-8(不是 UTF-8 with BOM) - 导入时强制指定编码:
psql -f dump.sql -v ON_ERROR_STOP=1 --set=client_encoding='UTF8' - 别信文件后缀或编辑器自动识别,用
file -i dump.sql(Linux/macOS)或 VS Code 底部状态栏确认真实编码
Navicat 的「编码自适应」听着智能,实际很不可靠;只要涉及中文,所有环节都得盯死 UTF-8 这一根线——从 initdb 到连接参数,再到文件保存和导入命令。漏一环,乱码就回来。










