当前位置: 首页 > news >正文

MySQL迁移Kingbase?一文告诉你有哪些语法兼容的坑

信创浪潮下,“MySQL & Oracle 兼容”是很多国产数据库厂商的标配宣传语,但兼容到什么程度、哪些细节会踩坑,往往只有真刀真枪的测过才知道。语法层面能跑通不代表业务逻辑能对齐,一个 REPLACE INTO 的主键校验差异,或者某些函数的执行结果不符合预期,都有可能在生产环境酿成事故。

本文以 Kingbase V9 为例,从多个维度验证其与 MySQL 在语法、函数等方面的实际表现,供各位朋友参考。

KingbaseES V009R001C010 MySQL 8.4.7 OS Linux 7.9

语法兼容测试

SQL 语法兼容性

Kingbase V9 支持show create table的方式获取具体的创建表 SQL,

但不支持通过show index from语法获取索引信息,

仍然需要通过传统的\d方式。

SHOW DATABASES/SHOW TABLES/SHOW VARIABLES/SHOW ENGINES等语法都不支持,好在是 Kingbase 中获取这类信息的方式也足够简便,并不会影响到实际的使用体验。

数据类型兼容性

MySQL 中常见的数据类型在 KingbaseV9 中都能够支持,类似 ZEROFILL 等极少部分特殊用法不支持。

对于数值类型的边界和枚举类型中的未知字符都能够很好的识别。

DML 兼容性测试

DML 兼容性测试中主要验证 MySQL 中比较特殊的 DML 用法,绝大多数常用的场景都是兼容的。

例如,INSERT IGNORE INTO 测试,Kingbase 和 MySQL 的预期结果一致。

但是在 REPLACE INTO 中却表现出了不同的结果,

CREATE TABLE t_replace (id INT PRIMARY KEY, sku VARCHAR(20) UNIQUE, stock INT); INSERT INTO t_replace VALUES (1, 'A001', 100); REPLACE INTO t_replace VALUES (1, 'A001', 200); REPLACE INTO t_replace (sku, stock) VALUES ('A001', 50); SELECT * FROM t_replace;

这段代码中的第二条 REPLACE INTO 语句,在 MySQL 中因为缺少主键没有能执行成功,但在 KingbaseV9 中却直接忽略主键更新了其中的数据,导致两者结果不一致。

这里不深究两者实现上的底层逻辑,因为是测试 Kingbase 对于 MySQL 的兼容性,那么我认为这个场景是不符合预期的。

如果说上述结果有可能只是设计逻辑上的差异,那么接下来的这段测试结果就更加让人摸不着头脑。

CREATE TABLE t_replace (id INT PRIMARY KEY, sku VARCHAR(20) UNIQUE, stock INT); INSERT INTO t_replace VALUES (0, 'A000', 100); INSERT INTO t_replace VALUES (1, 'A001', 100); INSERT INTO t_replace VALUES (2, 'A002', 100); REPLACE INTO t_replace VALUES (1, 'A001', 200); REPLACE INTO t_replace (sku, stock) VALUES ('A001', 50);

没有详细分析具体的原因,MySQL 是 InnoDB 引擎,对于 update 采用的是原值更新的方式;而 Kingbase 的更新采用的是“版本追加”的方式,更新前后的数据都存在,通过事务 ID 来控制数据是否可见。猜测可能是由于版本控制上的异常导致这种情况的发生。

函数兼容测试

NULL 值处理测试

NULL 在数据库中是个特殊的数据,不同的数据库对于 NULL 值的处理常常有一定的差别。

测试结果倒是让我有些意外,本以为两者之间会有比较大的差异,测试下来发现 IFNULL、COALESCE、LOCATE、SUBSTRING_INDEX、GROUP_CONCAT 等函数在处理空值的行为都是一致的。

但是也遇到了一个特殊情况, 在使用 SELECT LPAD(‘ab’, 5, ‘’); 进行填充测试的时,MySQL 返回的是空值,而 Kingbase 则返回的是 ‘ab’ 字符。

比较奇怪的是,两者在处理 NULL 和 ‘’ 值的行为是一致的,为什么会出现上图的现象,有机会向 Kingbase 的开发人员讨教一二。

开窗函数兼容测试

开窗函数中大部分的语法都是兼容的,但是在 LAG 函数上有些差异。

CREATE TABLE t_sales ( id INT PRIMARY KEY, dept VARCHAR(10), emp_name VARCHAR(20), salary DECIMAL(10,2), sale_date DATE ); INSERT INTO t_sales VALUES (1, 'A', 'Tom', 8000, '2026-01-05'), (2, 'A', 'Jerry', 9000, '2026-01-10'), (3, 'A', 'Anna', 9000, '2026-01-15'), (4, 'B', 'Mike', 7000, '2026-01-08'), (5, 'B', 'Lucy', 7500, '2026-01-12'), (6, 'B', 'John', 6000, '2026-01-20'); -- 测试SQL1 SELECT dept, emp_name, sale_date, salary, LAG(salary, 1) OVER (PARTITION BY dept ORDER BY sale_date) AS prev_salary, LEAD(salary, 1) OVER (PARTITION BY dept ORDER BY sale_date) AS next_salary FROM t_sales; -- 测试SQL2 SELECT dept, emp_name, sale_date, salary, LAG(salary, 1, 0) OVER (PARTITION BY dept ORDER BY sale_date) AS prev_salary, LEAD(salary, 1, 0) OVER (PARTITION BY dept ORDER BY sale_date) AS next2_salary FROM t_sales;

上述测试 SQL1 的预期结果是,按照 sale_date 排序后,每行取同 dept 内上一条/下一条的 salary,第一行的 prev_salary 和最后一行的 next_salary 均为 NULL。两库的测试结果均符合预期。

测试 SQL2 的预期结果是,如果 prev_salary 的前值和 next_salary 的后值为空的情况下,取其默认值。

这个测试中,MySQL 的结果是符合预期的;

但 Kingbase 直接报错了,从报错信息上看应该是参数上的错误。

从 Kingbase 官网上的文档看,LAG 函数是支持默认值参数的,而且根据官方给出的测试案例也是能够执行成功的,具体的文档参考 https://docs.kingbase.com.cn/cn/KES-V9R1C10/application/application-develop-guide/reference/mysql/functions_operators/window_functions#lag。为什么上述的测试 SQL2 会报错,也希望能够得到 Kingbase 开发人员的分析和解释。

JSON 函数测试

JSON 支持也是各大数据库重点宣传的功能之一,因此这里将 JSON 单列出来进行测试。

常规的插入和更新操作,Kingbase 和 MySQL 的预期行为一致,数据更新和插入过程中都会严格验证是否符合 JSON 语法,对于错误的数据是不允许插入的。

同时对于更高阶的嵌套路径访问和数组下标访问等场景,两个数据库表现出来的结果均符合预期。

CREATE TABLE t_json ( id INT PRIMARY KEY, data JSON ); INSERT INTO t_json VALUES (1, '{"name":"Tom","age":20,"tags":["a","b","c"],"addr":{"city":"Hangzhou","zip":"310000"}}'), (2, '{"name":"Jerry","age":25,"tags":["b","d"],"addr":{"city":"Shanghai","zip":"200000"}}'), (3, '{"name":"Anna","age":null,"tags":[],"addr":null}'); -- '->'和'-->'操作符 -- 预期: raw_name带双引号 "Tom",unquoted_name不带引号 Tom(->>相当于JSON_UNQUOTE(JSON_EXTRACT(...))) SELECT id, />

和在 MySQL 中的执行结果是一致的。

写在最后

从总体测试结果来看,Kingbase V9 和 MySQL 的兼容性还是非常不错的,绝大部分的 SQL 语法和函数都不需要任何改造,可以直接使用。

不过对于一些特殊的用法,尤其是 MySQL 特有的“方言”的使用上,有些部分还是存在一些差异的。这也提醒我们数据库的迁移改造需要经过严格的测试验证,不要等到上线后发现问题再去调整。

最后声明一点,虽然在这篇文章里列举了不少兼容性上的差异,是因为对于预期结果一致的部分一笔带过了,仅仅将差异部分记录了下来。

http://www.jsqmd.com/news/1221370/

相关文章:

  • 让批改更高效、让解题更生动,合合信息“蜜蜂AI”携AI教育新场景亮相WAIC
  • 江诗丹顿官方服务项目及价格查询|全部地址与24小时客服电话权威信息通告(2026年7月最新) - 江诗丹顿服务中心
  • 大模型上下文窗口选型决策手册(2024企业级实测白皮书)
  • 救命!2026年AI论文网站排行榜,格式改到崩溃的应届生直接抄作业
  • ONE. shell及Linux命令
  • Blender动画GIF一键导出:用Bligify插件告别繁琐转换!
  • 2026供应链残酷真相:加班越多越廉价!SCMP帮你跳出时长内卷,靠效率升职
  • 用飞算JavaAI搭建融汇智能支付与清结算平台:让交易安全、清晰、可追溯
  • 5步实现Figma到Unity的UI设计无缝转换:告别手动复制的终极解决方案
  • 宁波名表回收实操手册:机芯表盘表带表扣逐一检查完整流程 - 大牌深度测评
  • bootstrap3-wysiwyg事件处理全解析:提升编辑器交互体验的终极指南
  • 2026淮安黄金回收优选回收渠道:这五家规范门店让你卖得明白放心 - 商业快讯早知道
  • AI 驱动的性能回归检测:合约与前端变更的自动化 Benchmark 与瓶颈定位
  • 5分钟快速掌握ChanlunX:通达信缠论分析插件终极指南
  • 2026年7月最新萧邦泉州台商宝龙广场维修保养服务电话 - 萧邦中国官方服务中心
  • 别再用笨办法复盘球赛了!我用AI工具,1小时搞定阿根廷vs西班牙的10篇爆款内容
  • 福州首饰回收行情浮动大!选对渠道才不亏本金 - 大牌深度测评
  • 芯片采购平台推荐:如何找到稳定可靠的IC供应渠道?
  • 2026年国内大理石量具供应 适配多场景优质企业排行 - 资讯纵览
  • 3步掌握Diffuse:Android开发者必备的二进制文件对比神器
  • 数字经济专业考什么证书对就业有帮助?
  • 冒泡排序与选择排序完整对比解析
  • 爱彼中国官方售后服务中心|官方热线及全部网点地址权威信息公示(2026年7月更新) - 爱彼中国官方服务中心
  • 3分钟掌握缠论分析:通达信ChanlunX插件完全指南
  • STM32烧录方式全解析:从串口到SWD实战指南
  • ARM---基于I.MX6ULL的启动代码,汇编点灯,交叉编译以及对I.MX6ULL相关寄存器的介绍
  • 武汉别墅设计工作室怎么选?意米设计实话拆解高口碑高还原实力 - 品牌红黑榜
  • 基于SpringBoot的爱宠宠物寄养管理系统的设计
  • 8GB显存也能玩转AI视频生成!ComfyUI-FramePackWrapper让你在普通显卡上创作高清视频
  • 5个理由告诉你:为什么这款免费开源卡拉OK游戏值得你立即尝试