☰
Navicat 连接 KingbaseES:建库、导数与迁移校验实战
2026/10/27 2:42:33 网站建设 项目流程

简介:面向需要连接和管理人大金仓数据库的开发、运维及数据迁移人员,这份实操型文档以 Navicat 为工具,围绕连接配置、对象管理与 SQL 操作梳理常见流程,适合具备基础数据库概念、希望减少试错成本的读者查阅。压缩包内含 1 个 docx 文件,约 1.62MB,体量轻便,适合随项目留存或按章节检索。正文从 Navicat 的定位与安装入手,覆盖新建连接、账号密码配置、连接成功后的库表管理,以及创建数据库、转储 SQL 文件、复制为插入语句、执行 SQL 等环节,并对排序规则、字符集一致性和账号权限等易错点作出提示。已有 1300 人学习,可作为连接人大金仓时排查配置、完成数据导出导入与 SQL 调试的步骤化参考,目录按操作顺序组织,并单独列出注意事项,便于按连接、建库、导出、查询等场景快速定位所需内容。

1. KingbaseES 配 Navicat:一条被低估的连接路径

甲方机房只给了一台跳板机,上面装了 Navicat,没装官方客户端,而你要连的是金仓 KingbaseES 数据库——这种场景在国产化替换的项目里出现频率极高。KingbaseES 的服务端走的是 PostgreSQL 那套前端/后端协议,默认监听 54321 端口,所以 Navicat 里选「PostgreSQL」类型、把端口从 5432 改成 54321,大概率就能连上,SQL 编辑、建库、转储、批量执行这些日常操作一样不落。这篇面向的是手上只有 Navicat、需要在 KingbaseES 上完成建库、导数、迁移验证的从业者;新手能照着步骤走通,熟手能在这里看到编码、排序规则、类型映射这几个真正会翻车的边界。

2. 连之前先搞清三件事:协议口、驱动面、编码面

动手点「新建连接」之前,有三件事必须先确认清楚,否则后面每一分钟都在跟报错搏斗。分别是服务端到底在哪个端口上听、Navicat 用哪套客户端库去握的手、以及库的编码在建库那一刻被定成了什么。这三件事的答案决定了连接参数怎么填、SQL 怎么写、导出的文件能不能灌回去。

2.1 为什么在 Navicat 里要选 PostgreSQL 而不是「其他」

Navicat 的连接类型下拉里没有「KingbaseES」这一项,很多人第一反应是去选「其他」或者「通用」,结果卡在驱动配置上。正确做法是选 PostgreSQL。原因在于 KingbaseES 的服务端实现了与 PostgreSQL 兼容的前后端通信协议:客户端发起启动包、服务端回认证请求、之后走查询/结果集的消息流,这一整套握手格式是对齐的。Navicat 的 PostgreSQL 连接本质上是内置了一份 libpq 客户端库在跑这套协议,只要服务端认这套报文,连接就能建立。

提示:这里说的「兼容」是通信协议层面,不是 SQL 语法和系统表层面。协议通了只代表能连上、能跑简单查询,语法差异要靠后面的兼容模式来兜。

这也解释了一个常见现象:同一个 Navicat,连原生 PostgreSQL 一切正常,连 KingbaseES 却偶发「unsupported frontend protocol」或者认证阶段直接断开。多数情况是客户端库版本与服务端内核版本差得太远,握手阶段协商的协议小版本对不上。我一般会先用一台机器上的 ksql 命令行验证服务端本身没问题,再去怀疑 Navicat 这一端,这样能把问题范围砍掉一半。

# 先用服务端自带客户端确认库是活的,排除网络和账号密码问题 ksql -h 10.0.0.21 -p 54321 -U system -d test -c "select version();" # 确认服务端编码、排序规则、兼容模式,这三项后面全部要用到 ksql -h 10.0.0.21 -p 54321 -U system -d test -c "show server_encoding;" ksql -h 10.0.0.21 -p 54321 -U system -d test -c "select datname, pg_encoding_to_char(encoding), datcollate, datctype from sys_database;"

第一段命令验证连通性和账号口令,返回版本串说明网络、端口、认证三关都过了,剩下就是 Navicat 客户端的事。第二、三段是重点:server_encoding给出服务端编码,通常是 UTF8;sys_database里能一次看到所有库的编码、collate、ctype,后面建库时照着对齐就行。注意系统表前缀是sys_,老脚本里写pg_database的不一定能直接跑,遇到报「关系不存在」先换前缀试试。

2.2 端口、库名、账号:三个最容易填错的字段

Navicat 的 PostgreSQL 连接表单里,默认端口是 5432,主机填对了、端口忘了改,表现是连接超时而不是拒绝,很容易被误判成防火墙问题。KingbaseES 初始化时默认端口是 54321,装的时候如果有人改过,就得去服务端配置文件里翻实际值。

「数据库」这一栏也经常出问题。留空的话,Navicat 会尝试连一个与用户名同名的库,服务端找不到就回一句 database "xxx" does not exist。稳妥的填法是直接写初始库名,一般初始化完会有一个test库可用,连上之后再在里面建业务库。

账号方面,默认的超级用户是system,口令在初始化数据库时设定,不在配置文件里。部分做了安全加固的部署会启用权限分离,管理员、安全员、审计员拆成不同账号,这时候拿system去连可能被策略挡掉,需要向部署方确认到底给的是哪个角色。我踩过一次:给了个只读账号,连上后建库一直报权限不足,折腾了半小时才发现是账号本身没有 createdb 权限,跟 Navicat 一点关系没有。

连接参数我整理成一张表,填之前对着核一遍:

字段常见值填错的典型表现
连接类型PostgreSQL选「其他」时驱动配置为空,无法握手
主机服务端 IP 或域名填 127.0.0.1 连到本机,报拒绝连接
端口54321(默认)沿用 5432,长时间无响应后超时
初始数据库test 或业务库名留空,报 database 不存在
用户名system 或分配的业务账号权限不足,建库/建表被拒
密码初始化时设定认证失败,注意大小写与特殊字符转义

2.3 客户端编码先于建库确定

编码这件事的顺序很关键:服务端编码在 initdb 那一刻就固定了,之后不能改;客户端编码是会话级的,可以随时设;而 Navicat 作为客户端,它自己还有一个「连接编码」的设置项。三层里任何一层和其他层不一致,中文就会在某个环节变成问号或者一堆看不懂的字节。

常见做法是:先查清server_encoding,如果是 UTF8,就把 Navicat 连接属性里的编码也固定成 UTF-8,别用「自动」。自动模式在服务端返回的编码名与客户端库预期不完全一致时,会退回到一个保守值,导出的 SQL 文件里中文就成了乱码,而且这个乱码是写进文件的,灌回去就是脏数据。

-- 在 Navicat 的查询窗口里执行,确认当前会话三层编码是否一致 show server_encoding; -- 服务端编码,建库时定死,改不了 show client_encoding; -- 当前会话的客户端编码,可会话级调整 show lc_collate; -- 排序规则,影响比较与索引,不影响存储字节 -- 如果客户端编码不是 UTF8,会话内临时纠正(只对当前连接有效) set client_encoding to 'UTF8';

这三条show是排查乱码的第一步,永远先看它们再看数据。server_encoding和client_encoding都是 UTF8 时,中文在传输链路上就不会被转码;lc_collate影响的是排序和比较结果,不直接产生乱码,但迁移时如果两边不一致,order by出来的顺序会变,唯一索引的去重行为也可能不同,所以建库时一起对齐最省事。set client_encoding只对当前会话有效,断开重连就失效,属于临时止血,不是根治手段。

3. 建连接与建库:把字符集和排序规则一次定死

连接建起来只是开始,真正决定后面顺不顺的是建库那一条语句。库建错了编码或者排序规则,后面所有的导入导出都是在这个错误基础上叠加,越往后成本越高。这一章把新建连接、测试、建库、schema 对齐四步串起来,每一步都给到可以直接抄的参数。

3.1 新建连接与测试:把参数一次填对

打开 Navicat,左上角「连接」→「新建连接」→「PostgreSQL」。表单里按上一章那张表填:主机写服务端地址,端口写 54321,初始数据库写test,用户名system,密码照填。填完先别急着点「确定」,点左下角的「测试连接」,这一步会把 TCP 连通、协议握手、认证三个阶段分别走一遍,报错信息比直接保存后再连要具体得多。

测试通过后点「确定」保存,双击连接名展开,能看到数据库列表、角色、表空间这些节点。第一次展开如果转圈很久,通常是服务端在枚举大量对象,或者网络 RTT 偏高,可以在连接属性里把「保持连接间隔」调小一点,让 Navicat 定期发心跳,避免中间设备把空闲连接掐掉,表现出来就是「放着不动十分钟,再点就报连接已断开」。

注意:连接属性里的 SSL 选项卡,如果服务端没开 SSL 而客户端选了 require,握手会直接失败;反过来服务端强制 SSL 而客户端选 disable,也一样连不上。不确定就先试 disable,能连上说明服务端没强制。

保存好的连接可以右键「复制连接」,改个名字和库名就是一套环境,测试、预发、生产各一份,比每次重新填参数靠谱。密码如果不想每次输,勾上「保存密码」,但要清楚这是存在本地配置文件里的,共用机器上别这么干。

3.2 建库语句:编码与排序规则一起定

在连接上右键「新建数据库」是图形化路子,填个名字点确定就完事,但字符集和排序规则那一栏经常被忽略,默认值未必是你要的。我一般直接用 SQL 建,参数写得明明白白,也方便复制到别的环境重复执行。

-- 建业务库:编码与排序规则显式指定,模板必须用 template0 create database appdb with encoding = 'UTF8' lc_collate = 'C' lc_ctype = 'C' template = template0; -- 建完立刻确认,避免建出来和预期不一致 select datname, pg_encoding_to_char(encoding) as enc, datcollate, datctype from sys_database where datname = 'appdb';

第一条语句里,encoding定死 UTF8;lc_collate和lc_ctype都写C;template必须是template0。第三点是硬性约束:template1里可能已经装了扩展或者改过编码,用它做模板时新库的编码和排序规则会被继承,显式指定的参数可能被拒绝或者被静默忽略。用template0相当于从一张白纸开始,参数说什么就是什么。

第二条语句是自检,sys_database里三个字段一次看全。如果建出来datcollate不是C,说明模板或者参数写错了,别急着往里灌数据,drop 掉重建,代价最小。

3.3 C 与 zh_CN.UTF-8 的取舍

排序规则选C还是zh_CN.UTF-8,是这套流程里唯一需要动脑子的决策。不少教程把乱码归罪到排序规则上,实际排查下来编码不一致才是乱码主因,排序规则影响的是比较、排序和索引行为。但迁移场景下两者一起对齐,能省掉后面一堆「为什么同样数据在两边 order by 结果不一样」的追问。

维度Czh_CN.UTF-8
排序依据字节序依操作系统 locale 的语言规则
中文 order by按 UTF-8 字节排,非拼音序接近拼音序(依赖 locale 实现)
跨平台一致性高,不依赖 OS低,换机器可能行为不同
建库失败风险低locale 未安装时可能直接建不出来
大小写与比较按字节严格比较受 locale 规则影响

结论比较清楚:如果这套库要跨环境迁移、要做主备或多节点部署,选C,行为稳定、可预期,代价是order by中文不是拼音序,需要排序时在应用层或者用order by convert_to(col,'UTF8')之类的方式处理。如果业务强依赖数据库层的拼音排序,那就选zh_CN.UTF-8,但要确保所有目标机器的 locale 都装了,否则建库那一步就过不去。

还有一点容易忽略:图形工具建库和 SQL 建库的默认值可能不一样。用自带管理工具点出来的库,排序规则常常是zh_CN.UTF-8;用 Navicat 走 SQL 建,默认跟着模板走。两边混着用,同一套系统里就出现了两种排序规则的库,后面跨库查询、数据同步都可能出问题。定一条规矩:这套环境里所有库统一用同一条建库语句,谁建都一样。

3.4 建表前的 schema 与 search_path 对齐

库建好了,表还没建,这时候要先想清楚 schema 放哪。KingbaseES 默认有public模式,建表不写 schema 就落在这里。但如果是 Oracle 兼容模式下初始化的库,很多对象是按用户名建 schema 的,直接create table t(...)会落到与当前用户同名的 schema 下,和预期不一致。

-- 看当前会话的 schema 搜索顺序 show search_path; -- 显式建 schema 并把搜索路径固定下来,避免对象乱落 create schema if not exists app; set search_path to app, public; -- 建表时也可以写全限定名,最不容易出错 create table app.t_order ( id bigint primary key, order_no varchar(64) not null, amount numeric(18,2), created_at timestamp default now() );

show search_path是最快的确认手段,输出里第一个就是默认落点。set search_path只对当前会话有效,长期生效要改库级或角色级配置,我一般两类都做:会话里设一次保证当前脚本不出错,再在连接属性或者库级参数里固化,避免换个窗口就变回去。建表语句写全限定名是最笨也最有效的办法,尤其在多人共用一套库的时候,谁都不会把表建错地方。

4. 转储、复制插入与批量执行:三条导数据路径怎么选

连上、建完库,接下来就是数据进出。Navicat 在这一块提供了三条路径:转储 SQL 文件、复制为插入语句、SQL 编辑器批量执行。三条路径适用的数据量、字段类型、容错要求完全不同,用错了不是慢,是直接卡死或者导出一堆不可用的内容。这一章把三条路径的边界说清楚。

4.1 转储 SQL 文件:选项决定成败

在库或者表上右键「转储 SQL 文件」→「结构和数据」,弹窗里有几个勾选项,默认值不一定适合迁移场景。

-- 转储前先估算体量,决定用文件还是分批 select relname as table_name, n_live_tup as approx_rows, pg_size_pretty(pg_total_relation_size(relid)) as total_size from sys_stat_user_tables order by pg_total_relation_size(relid) desc limit 20;

这条查询用sys_stat_user_tables拿到每张表的近似行数和占用空间,按大小倒序排。n_live_tup是统计信息里的估算值,不精确但足够判断量级:几万行以内,转储成一个文件没问题;上百万行、或者单表超过几百兆,转储出来的 SQL 文件在编辑器里打开就卡,灌回去时也容易因为单条语句过长而失败,这种要拆表分批。

弹窗里几个选项的含义:勾「包含 BLOB」才会把大对象和二进制字段写进去,不勾的话字段值直接是空,导过去就是一堆 NULL,还不报错;「遇到错误继续」在目标端已有部分数据时有用,但它会把错误吞掉,第一次全量导入我一般不开,宁可中途失败也要看清第一条错误;「锁定表」在源库还有写入时能保证一致性,代价是导出期间业务写不进去,生产环境要挑时间窗。

4.2 复制为插入语句:只适合小批量

在结果集里选中若干行,右键「复制为插入语句」,得到一串insert into ... values (...)。这个功能做临时数据搬运用着很爽,但它有明确的适用边界:行数少、字段类型简单、不含大文本和二进制。

几万行的结果集上点这个,Navicat 会先把整个结果集在内存里拼成字符串,界面直接假死,等它缓过来可能已经过去几分钟。更麻烦的是内容层面:text字段里如果有单引号、换行,生成的语句里转义处理未必符合目标端语法;bytea字段会变成一串十六进制,粘过去可能超长被截断。我见过有人拿这个功能搬一张带附件的表,导过去的文件全打不开,回头查了半天以为是传输问题,其实是复制那一步就已经废了。

判断标准很简单:几十行、全字符和数值字段,用它;上百行以上,或者有text、bytea、json这类字段,老老实实走转储文件或者命令行。省下来的时间够你泡杯茶。

4.3 SQL 编辑器批量执行与命令行兜底

Navicat 的查询窗口执行大脚本有两个坑。一是整个脚本被当成一个批次提交,中途报错后前面的语句是否回滚取决于自动提交设置;二是超大文件在编辑器里加载本身就慢,几万行的 SQL 文件打开要等,光标移动都卡。

# 大脚本走命令行更稳,-v ON_ERROR_STOP=1 让它在第一条错误处停下 ksql -h 10.0.0.21 -p 54321 -U system -d appdb \ -v ON_ERROR_STOP=1 \ -f /data/dump/appdb_schema.sql # 只看执行到哪一步、报了什么,把输出重定向留档 ksql -h 10.0.0.21 -p 54321 -U system -d appdb \ -v ON_ERROR_STOP=1 \ -f /data/dump/appdb_data.sql > /data/dump/load.log 2>&1

-v ON_ERROR_STOP=1是关键参数,默认情况下 ksql 遇到错误会继续往下跑,一个字段类型不对可能引发后面几十条语句连锁失败,日志里几百行错误反而看不出根因。加上这个参数,第一条错就停,日志干净,定位快。-f指定脚本文件,输出重定向到日志留档,出问题能回溯到具体哪一行。

小脚本、临时改数据,还是在 Navicat 的查询窗口里方便:选中要执行的那几条,Ctrl+Shift+R只跑选中部分,比整个窗口全跑安全。改数据之前先begin,看一眼影响行数再commit,这个习惯能救不少次手滑。

5. 排查与避坑:五类现场故障的现象、原因和处置

下面这五类问题,基本覆盖了用 Navicat 连 KingbaseES 时九成以上的翻车现场。每条按现象、原因、处置三段写,遇到时对着比一遍,比漫无目的地搜要快。

5.1 连接超时或直接被拒

现象:点「测试连接」转很久最后报超时;或者秒回「connection refused」。

原因分两种。超时一般是端口填错(还在用 5432)或者中间有防火墙挡着,SYN 包发出去没有回应。秒拒是目标 IP 可达但那个端口上没有进程在听,可能是服务没起,也可能是监听地址只绑了 127.0.0.1,外部连不进来。

处置:先在服务端机器上ksql -h 127.0.0.1 -p 54321 -U system -d test确认本地能连,本地通说明服务是活的;再看配置文件里的监听地址是不是只写了回环,改成对外地址后重启服务;最后从客户端机器telnet 目标IP 54321看端口通不通,不通就找网络侧。

5.2 中文变问号或者乱码

现象:查询结果里中文显示成???,或者一堆\xxx转义;导出的 SQL 文件用文本编辑器打开是乱码。

原因:三层编码不一致。服务端 UTF8、客户端连接设成了别的编码,服务端会把中文转成目标编码,转不了就变问号;或者导出时用了错误的字符集写文件,文件本身是好的但打开方式不对。

处置:先show server_encoding和show client_encoding对比,不一致就在连接属性里把编码固定成 UTF-8;导出的文件用支持 UTF-8 的编辑器打开确认,别用系统默认编码的记事本下结论;已经导出成乱码的文件不要试图修复,重新导一次,成本更低。

5.3 转储文件灌回去报语法错误

现象:导出的 SQL 在目标库执行,前几条就报syntax error at or near ...。

原因:源库和目标库的兼容模式不同。Oracle 兼容模式下某些 DDL 写法、系统函数、类型名和 PostgreSQL 模式不一样,转储出来的语句直接拿到另一个模式的库上跑,语法对不上。

处置:确认两边库的兼容模式是否一致,不一致的话不要指望原样灌,改用「数据传输」功能走结构映射,或者在导出时只导数据、结构在目标端单独建。另外系统表前缀差异也要留意,脚本里写pg_的在某些版本上要换成sys_。

5.4 类型映射走样

现象:text字段导过去变成了别的类型,boolean变成了bit,数值精度少了两位,日期多了时区。

原因:Navicat 在做跨类型数据库传输时会做类型映射,它按自己的映射表来,不完全等同于目标库的原生类型体系。字段越多、类型越偏,走样的概率越高。

处置:迁移前先只导结构,把生成的 DDL 逐条看一遍,重点核numeric的精度标度、timestamp带不带时区、大文本用的是text还是clob。定好映射规则后再导数据,别一键到底。校验阶段用行数加关键字段聚合值对比,比抽样看几行靠谱。

5.5 权限与大小写

现象:连上了但看不到表;或者能看到表,查询报「关系不存在」;建表报权限不足。

原因:看不到表多半是 schema 和search_path不匹配,表在app模式下而当前搜索路径只有public。报关系不存在还有一个高频原因是大小写:建表时用了双引号包住大写标识符,之后不加引号查就找不到,因为不加引号会被折叠成小写。

处置:show search_path确认路径,必要时set search_path或写全限定名;对象名统一用小写加下划线,别用双引号造大写名,这个规矩定下来能省掉后面无数的引号问题;权限问题查角色成员关系和库级connect、schema 级usage、表级select/insert三层授权,缺哪层补哪层。

6. 进阶:把连接和迁移流程固化成一张检查单

做到这里,单次连接和单次导数都不是问题了,真正拉开差距的是可重复性——同一套动作,换个人、换个环境、隔三个月再做,结果要一样。我一般会把整条链路固化成一张检查单,配上两段校验脚本,每次迁移完强制跑一遍。

-- 迁移后校验:行数、关键字段聚合、空值分布三件套 select 't_order' as tbl, count(*) as rows, sum(amount) as amount_sum, count(*) filter (where order_no is null) as null_cnt from app.t_order union all select 't_user', count(*), null, count(*) filter (where name is null) from app.t_user; -- 字符集与排序规则的一致性核对,两个库分别跑一次对比结果 select datname, pg_encoding_to_char(encoding) as enc, datcollate, datctype from sys_database where datname in ('appdb', 'test');

第一段把每张表的行数、可加总字段的合计、关键字段的空值数一次算出来,源库和目标库各跑一次,把结果并排贴在一起看。行数对上只能说明条数没错,金额合计对上才说明没有截断或者精度丢失,空值数对上说明没有把空串写成 NULL 这类静默转换。这三项里任何一项不一致,都值得停下来查清楚再往下走。

第二段是环境一致性核对,编码和排序规则这两个字段必须两边完全一样,否则后面所有的比较、排序、唯一约束行为都可能出现细微差异,而这种差异往往在业务跑了几个月之后才暴露。

# 两库行数逐表对比,输出差异表;差异为空才算通过 for t in t_order t_user t_item; do src=$(ksql -h 10.0.0.21 -p 54321 -U system -d appdb -tAc "select count(*) from app.$t") dst=$(ksql -h 10.0.0.22 -p 54321 -U system -d appdb -tAc "select count(*) from app.$t") if [ "$src" != "$dst" ]; then echo "DIFF $t src=$src dst=$dst" fi done

-tAc三个参数分别是去掉表头、只输出元组、单行模式,拿到的就是纯数字,方便直接比较。表名列表放在for里,表多了就写进一个文件用while read遍历。这个脚本不用多精巧,能在 CI 或者发布流程里跑一次、有差异就退出非零,价值就出来了。

再往上走一层,是把 Navicat 里的连接配置也当成资产管起来:每个环境一个连接,命名带上环境前缀,敏感信息不落本地而是走统一口令管理,团队里谁接手都能在五分钟内连上正确的库。工具本身不难,难的是让每次操作都可复现、可核对。

血泪经验是一条:我曾经因为图省事,在同一个实例上混用了两种排序规则建库,测试环境一切正常,上线后跨库关联查询的排序结果和分页数据对不上,查了两天才定位到datcollate不一致。从那以后我每次建库前都强制走一遍sys_database核对,建完再核一次,宁可多花三十秒,也不愿再经历一次那种排查。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询