从 mysql 命令切到 ksql,第一步先把连接搞明白
数据库装好以后,第一件事不是建业务表,也不是急着看复杂语法,而是先确认客户端能不能稳定连进去。
MySQL 用久了,手上一般会有一套很熟的动作:服务起来以后,敲一条 mysql -h -P -u -p,能进交互界面,再查个 select version()。这套动作看起来简单,但它解决的是最基础的问题:当前连的是哪台机器、哪个端口、哪个用户、哪个库。
切到 KingbaseES 以后,入口换成了 ksql。命令也不复杂,不过几个参数不能直接按 MySQL 的习惯套。尤其是数据库名这一项,如果没显式写出来,很容易遇到一个看起来像连接失败、实际只是默认库不对的错误。
先确认用的是哪个 ksql
安装目录里不止有数据库服务端程序,也有客户端工具。开始连库之前,先确认当前 shell 里找到的 ksql 来自哪里。
bash
which ksql
ksql --version
ksql --help | head -n 40
当前环境里,ksql 来自安装目录下的 Server/bin:
text
/acowbo/kingbase/install/KESRealPro/V009R001C010/Server/bin/ksql
版本返回的是:
text
ksql (KingbaseES) V009R001C010

这一步看着普通,但后面排查问题时很有用。机器上如果装过多个版本,或者 PATH 里混进了别的客户端工具,先确认命令来源能省不少时间。
ksql --help 里也能看到它自己的参数习惯。比如数据库名使用 -d,用户名使用 -U,端口使用 -p。这几个大小写和 MySQL 不完全一样。
text
MySQL:
mysql -h 127.0.0.1 -P 3306 -u root -p
KingbaseES:
ksql -h 127.0.0.1 -p 54321 -U system -d test
对 MySQL 用户来说,最容易顺手写错的是端口和用户名:MySQL 端口是大写 -P,用户是小写 -u;ksql 端口是小写 -p,用户是大写 -U。
这里还有一个细节:ksql 的帮助里把用法写成了 ksql [OPTION]... [DBNAME [USERNAME]]。也就是说,数据库名和用户名除了用参数指定,也能放在命令最后。实际写文章或脚本时,用 -U、-d 会更清楚。
比如下面两种写法都能表达连接目标:
bash
ksql -h 127.0.0.1 -p 54321 -U system -d test
ksql -h 127.0.0.1 -p 54321 test system
前一种更适合放在文章和脚本里。参数名一眼能看出来,后面排查连接问题时也不会猜最后两个位置参数分别是什么。
少了数据库名,错误会有点绕
先看一条不完整的连接命令:
bash
ksql -h 127.0.0.1 -p 54321 -U system
输入密码后,返回的是:
text
FATAL: database "system" does not exist

这个错误不能马上往"服务没起来"或者"密码错了"上想。这里密码已经进入校验流程,服务端也有响应,真正的问题是没有指定要连接的数据库。
ksql 在没有 -d 的情况下,会尝试连接和用户名同名的数据库。当前用户名是 system,它就去找名为 system 的数据库。实例里没有这个库,于是报了 database "system" does not exist。
这点和 MySQL 的使用习惯很容易打架。MySQL 里很多时候先用管理员用户连进去,再 use 库名;而这里最好一开始就把目标数据库写清楚。
这类错误也提醒了一件事:连接数据库时不要只看"账号密码对不对"。主机、端口、用户、数据库名四个值是一起工作的。服务能响应、密码能通过,并不代表目标数据库一定存在。以后看到 could not connect to server、password authentication failed、database does not exist 这几类错误,也要分开判断,不能全当成同一种连接失败。
把 -d 写上,先连进 test
补上数据库名以后,连接命令变成:
bash
ksql -h 127.0.0.1 -p 54321 -U system -d test
这次能正常进入交互界面,提示符变成了:
text
test=#

这条命令里主要是四个参数:
text
-h 127.0.0.1 连接本机数据库服务
-p 54321 连接端口
-U system 登录用户
-d test 目标数据库
这里的 test 是初始化后可以连接的数据库。实际环境里可以换成自己的业务库或实验库,关键是不要让客户端去猜默认库。
提示符也能顺手看一下。test=# 里的 test 是当前数据库,后面的 # 和当前高权限用户有关。后面换成普通用户连接 app_db 时,提示符会变成 app_db=>。它不是权限检查工具,但能快速看出当前大概连在哪个库、用的是什么级别的用户。
连进去以后,先确认自己在哪
进入交互界面后,先查当前数据库、当前用户和版本:
sql
select current_database(), current_user;
select version();
当前返回结果里,数据库是 test,用户是 system,版本是 KingbaseES V009R001C010。

MySQL 里常用 select database();、select user(); 看当前位置。KingbaseES 这里换成:
sql
select current_database(), current_user;
命令不同,作用差不多。后面要创建用户、创建数据库、建表,先确认当前库和当前用户,能少犯很多低级错误。
再试一个最小查询:
sql
select 1;
然后用 \conninfo 看当前连接信息:
text
\conninfo
最后退出:
text
\q

这里顺手碰到了 ksql 里的另一类命令:反斜杠开头的是客户端元命令,不是 SQL。比如 \conninfo 查看连接信息,\q 退出客户端。元命令后面单独展开,这里先知道它不是发给数据库执行的 SQL 就行。
select 1; 这种 SQL 会被发送到数据库执行;\conninfo 和 \q 由 ksql 客户端自己处理。这一点和 MySQL 客户端里的部分命令有点像,比如 status、source、\q 这类动作不完全等同于 SQL。先把这个边界分清,后面看 \l、\d、\dt 时就不会困惑:为什么这些命令不用分号,为什么它们不是标准 SQL。
环境变量也能连
完整参数写熟以后,可以用环境变量减少重复输入。
bash
export KINGBASE_HOST=127.0.0.1
export KINGBASE_PORT=54321
export KINGBASE_USER=system
export KINGBASE_DATABASE=test
再执行:
bash
ksql
客户端会读取这些环境变量,直接连接到对应数据库。

环境变量适合固定连接目标。比如这台测试机一直连 127.0.0.1:54321 的 test 库,就可以少敲一串参数。
临时测试时,先放在当前终端即可,不急着写进 .bashrc。要确认当前 shell 里留了什么值,可以直接看:
bash
echo $KINGBASE_HOST
echo $KINGBASE_PORT
echo $KINGBASE_USER
echo $KINGBASE_DATABASE
换用户、换库、换服务器之前,最好先清掉旧值:
bash
unset KINGBASE_HOST KINGBASE_PORT KINGBASE_USER KINGBASE_DATABASE
这样再执行 ksql 时,就会回到手动传参的状态,不会带着上一次的连接目标。
别一直用 system 做实验
前面的连接都是用 system 做的。安装初始化阶段用它没问题,但日常写 SQL、试表结构、做小实验,最好不要一直使用管理员用户。
这里创建一个普通用户:
sql
create user app_user with password '<实验密码>' nosuperuser nocreatedb nocreaterole;
执行成功后返回:
text
CREATE ROLE
再用 \du 看角色列表,可以看到 app_user 已经存在。

这里有个细节:命令写的是 create user,返回却是 CREATE ROLE。这不是异常。官方文档里也能看到,CREATE USER 是 CREATE ROLE 的别名,区别在于 CREATE USER 默认带登录属性。也就是说,KingbaseES 这里的用户和角色体系是放在一起理解的。
这里不展开完整权限模型,只先做一个最小隔离:管理员用户负责创建资源,普通用户负责实验操作。
nosuperuser nocreatedb nocreaterole 这几个选项也不用背得太早,先看字面就够了:不是超级用户,不能创建数据库,不能创建角色。也就是说,app_user 只是一个普通登录用户。这样后面用它建表、插入数据时,能更接近日常应用账号的状态,而不是一直用管理员权限把问题盖过去。
创建用户时的密码只用于本地实验,公开内容里不要放真实密码。示例里可以写成 <实验密码>,实际操作时按自己的密码策略设置。命令输出里如果出现密码,也应该提前打码。
给普通用户建一个自己的数据库
用户创建好以后,再创建一个数据库,并把 owner 指向这个用户:
sql
create database app_db owner app_user;
执行成功后,用 \l 看数据库列表。app_db 出现在列表里,owner 是 app_user。

这里要把两个概念分清楚:用户和数据库不是一回事。app_user 是登录身份,app_db 是数据库。把 app_db 的 owner 指给 app_user,再用这个用户连接这个库,就不用一直依赖 system。
官方 CREATE DATABASE 文档里也有对应语法,OWNER 可以指定新数据库的所有者。创建数据库本身需要超级用户或者 CREATEDB 权限,这也是这里继续使用 system 来执行创建动作的原因。
和 MySQL 对比时,这里也容易有错觉。MySQL 里经常把"一个库 + 一个用户 + 一组授权"放在一起理解,业务上也会说"给某个用户建一个库"。KingbaseES 这里仍然可以这么组织实验环境,但概念上要分开:用户是用户,数据库是数据库,owner 是数据库的所有者,后面还会遇到 schema 和对象权限。当前这一步只先把用户和数据库绑定起来,不把权限体系一次讲完。
用普通用户重新连一次
退出当前连接后,换成普通用户连接新库:
bash
ksql -h 127.0.0.1 -p 54321 -U app_user -d app_db
进入后先确认当前身份:
sql
select current_database(), current_user;
返回的是 app_db 和 app_user。这说明连接目标已经从管理员用户的 test,切到了普通用户自己的数据库。

接着做一个很小的写入验证:
sql
create table t_ksql_conn_demo(id int, name varchar(50));
insert into t_ksql_conn_demo values (1, 'hello ksql');
select * from t_ksql_conn_demo;
结果能查到 hello ksql,说明这个普通用户不仅能连库,也能在自己的数据库里完成建表和写入。
到这一步,ksql 入门就不只是"连上了"这么简单。连接参数、默认数据库、当前用户、普通用户、数据库 owner,都已经串起来了。
这个小表没有业务含义,只是验证连接后的写入能力。比单纯执行 select 1 更进一步:select 1 只能说明查询能执行,建表和插入成功,才说明这个用户在当前数据库里确实有基本操作能力。后面要继续练 SQL,也可以从这个 app_db 开始,避免在 test 库里越堆越乱。
先把连接习惯改过来
从 MySQL 切到 ksql,第一关不是 SQL 方言,而是连接习惯。
mysql 常用的是:
bash
mysql -h 127.0.0.1 -P 3306 -u root -p
ksql 这里更建议一开始就写完整:
bash
ksql -h 127.0.0.1 -p 54321 -U app_user -d app_db
几个点最容易踩:
text
端口参数:MySQL 是 -P,ksql 是 -p
用户参数:MySQL 是 -u,ksql 是 -U
数据库名:ksql 最好显式写 -d
默认行为:不写 -d 时,可能尝试连接和用户名同名的数据库
管理员用户:system 用来初始化和管理,不适合所有实验都压在它身上