资讯详情

MySQL迁移到达梦数据库:SQL语法兼容改造与实战指南

📅 2026/10/19 10:46:59 | 华诺云谱 👁 阅读
MySQL迁移到达梦数据库:SQL语法兼容改造与实战指南
做MySQL迁移到达梦数据库这件事很多时候不是DBA主动挑的而是项目上要求数据库国产化替换应用又不能重写唯一的路就是把现有MySQL里的表结构、数据、存储过程、应用SQL整体搬过去。我在某项目里完整走了一遍这个流程最大的感触是单表数据迁移本身不复杂真正让人头疼的全在SQL语法兼容上——同样的SQL在MySQL里跑得好好的到了达梦就报语法错误、函数不存在、分页结果不对甚至NULL排序位置都不一样。这篇文章就把我实际踩过的坑、验证过能用的写法、以及整个迁移方案整理出来内容包括达梦迁移工具的使用、SQL语法差异对照、应用层改造要点和上线前的数据校验方法。准备把系统从MySQL换到达梦的读者可以直接拿这份清单当参考。1. 迁移前需要想清楚的事为什么迁、怎么迁1.1 典型迁移场景与前置评估MySQL迁移到达梦数据库最常见的是两类场景。一是新建项目直接选型达梦从一开始就按达梦语法开发二是存量系统改造MySQL已经跑了多年业务不能停要把整个数据库搬过去。我遇到的属于后者表结构几百张核心业务表数据量过亿还有几十个存储过程和视图。这种场景下没有重写一遍的选项只能做语法兼容改造加数据迁移。动手之前先把迁移范围摸清楚。不要上来就建连接导数据先用几分钟列一份对象清单我在实际项目里用这条SQL统计源库信息-- MySQL 侧统计所有对象数量 SELECT TABLE AS OBJECT_TYPE, COUNT(*) AS CNT FROM information_schema.TABLES WHERE TABLE_SCHEMA your_db UNION ALL SELECT VIEW, COUNT(*) FROM information_schema.VIEWS WHERE TABLE_SCHEMA your_db UNION ALL SELECT TRIGGER, COUNT(*) FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA your_db;存储过程和函数在MySQL侧用SHOW PROCEDURE STATUS和SHOW FUNCTION STATUS统计。对象清单列出来之后按四类分好普通表、视图、触发器、存储过程与函数。普通表的数据迁移可以靠工具解决视图和触发器大部分靠手工改写存储过程是最耗时间的部分要单独排期。如果对象清单里视图和存储过程超过几十个建议在项目计划里至少留出一周专门做语法改造别指望迁移工具能自动转换这些逻辑。数据量评估同样重要。可以先在MySQL里查每张表的大致行数和最大表的占用空间重点关注有没有超大表、中间表、日志表。数据量直接影响迁移方式几千万行以内可以用工具一次性导上亿行的表必须分批抽取。另外字符集一定要提前确认MySQL常用utf8mb4达梦初始化时选UTF-8两者都能覆盖常用中文但emoji这类四字节字符在部分达梦版本上支持有限需要在评估阶段就确定字段里是否存在类似内容。1.2 迁移主方案选型工具迁移、手工改造还是应用先行迁移方案没有统一答案我尝试下来最稳的组合是工具迁数据加手工改SQL。达梦自带的数据迁移工具DTSData Transformation Service负责把表结构、索引、约束和数据从MySQL搬过来这一步能解决70%的工作量。但工具的强项只是表和数据对视图、存储过程、触发器这些逻辑对象它往往只能生成一个半成品的建库脚本编译能不能通过是另一回事。所以方案里要明确DTS只承担结构和数据代码逻辑相关的一律手工处理。还有一种路线是先用工具从MySQL导出SQL文件比如mysqldump导出表结构再用文本编辑器做一次全局替换把MySQL方言改成达梦方言。这个方案适合表结构简单、没有复杂函数嵌套的场景。我刚开始也试过这条路后来放弃了——全局替换能处理AUTO_INCREMENT改成IDENTITY这类规则替换但无法处理LIMIT分页、ON DUPLICATE KEY UPDATE、JSON字段这类需要重写语法的内容替换完照样报错。手工方案更适合配合DTS使用用来补齐工具迁移不了的那部分对象。应用层改造不能拖到最后。Java后端用MyBatis的话Mapper XML里通常散落着大量MySQL专属语法这些SQL在DTS迁移过程中完全不会被触碰上线时才会暴露问题。我的建议是迁移启动的第一天就并行做应用SQL审计用正则把常见MySQL方言标记出来。项目经验是MyBatis XML里的SQL占比越大应用层改造的工作量越接近数据库侧的迁移工作量两边同时开工可以缩短整个项目的迁移周期。关于达梦的兼容模式多说一句。达梦数据库提供了兼容外部数据库语法的模式参数安装初始化时可以选择能把一部分MySQL语法直接放行包括反引号、部分内置函数的别名等。但实测下来兼容模式不是万能开关它能让简单查询通过遇到嵌套子查询、窗口函数配合特定排序规则、特殊聚合函数时照样报语法错误或结果不对。所以不建议把整个迁移方案押在兼容模式上当作辅助手段可以该改的SQL还是要改。2. 最容易出问题的SQL语法差异盘点2.1 分页查询与自增列高频报错第一名分页是所有业务系统里出现频率最高的SQL模式也是迁移后报错最集中的地方。MySQL的经典写法是LIMIT offset, count例如SELECT * FROM user ORDER BY id LIMIT 10, 20。达梦在这个写法上兼容得并不彻底有些版本能接受单参数的LIMIT n遇到LIMIT n, n这种两个参数的分页写法就可能直接抛语法错误。我用过的最稳妥的改法是统一换成LIMIT count OFFSET offset也就是SELECT * FROM user ORDER BY id LIMIT 20 OFFSET 10。如果你的Mapper XML里大量使用动态SQL拼分页建议直接在数据访问层做统一处理而不是逐条去改SQL语句。某项目里我们在分页插件层面直接把两个参数的Limit改写成OFFSET形式一处改动全局生效。还有一个经常被忽略的坑达梦对ORDER BY中的NULL排序位置和MySQL不一样MySQL默认认为NULL值比普通值小升序时排在最前达梦默认行为是NULL值最大升序时排在最后。分页查询一旦涉及可空的排序列翻页结果顺序会和原系统不一致用户立刻会发现。解决办法是在ORDER BY里明确写NULLS FIRST或NULLS LAST。自增列是另一个高频问题。MySQL用AUTO_INCREMENT达梦用IDENTITYDDL转换还算好办真正麻烦的是数据迁移后的自增计数不同步。DTS工具把数据插入达梦表后自增起点往往还停在初始值下一次应用插入新数据就会主键冲突。自增列的迁移建议在导入完成后单独检查不要依赖工具自动处理。另外达梦的IDENTITY列默认不允许直接插入显式值迁移工具需要特殊处理才能写入原ID这个细节在工具配置界面里要提前勾选好相关选项否则数据导进去就报错。2.2 函数映射对照日期函数、字符串函数、聚合函数函数是MySQL和达梦差异最大的部分也是语法改造工作量最重的地方。整理了一张我在实际迁移中验证过的对照表MySQL函数对应到达梦上可以这样写MySQL写法达梦推荐写法备注NOW()SYSDATE返回当前时间DATE_FORMAT(d, %Y-%m-%d)TO_CHAR(d, YYYY-MM-DD)格式化日期STR_TO_DATE(s, %Y-%m-%d)TO_DATE(s, YYYY-MM-DD)字符串转日期DATE_ADD(d, INTERVAL 1 DAY)DATEADD(DAY, 1, d)日期加减天数DATEDIFF(d1, d2)DATEDIFF(d1, d2)天数差两边语法接近IFNULL(a, b)NVL(a, b)空值替换达梦也支持IFNULLCONCAT(a, b, c)CONCAT(a, b) 或 aGROUP_CONCAT(x ORDER BY y)LISTAGG(x, ,) WITHIN GROUP (ORDER BY y)聚合拼接IF(expr, a, b)CASE WHEN expr THEN a ELSE b END条件表达式REPLACE(a, b, c)REPLACE(a, b, c)两边基本一致日期函数是最容易漏改的因为很多开发写习惯了DATE_FORMAT和STR_TO_DATE到了达梦这两组函数名虽然能识别但格式化占位符完全不一样%Y换成YYYY这种细节最容易出错。聚合函数里最典型的是GROUP_CONCATMySQL里一句很常规的分组拼接达梦没有同名函数需要用LISTAGG加WITHIN GROUP (ORDER BY ...)的写法。列转行相关的函数两边也存在差异如果原SQL里用了SUBSTRING_INDEX这类函数大概率需要重构成达梦支持的SUBSTR加INSTR组合。字符串拼接也值得单独说。MySQL的CONCAT可以接收多个参数直接传三个字段拼一列没任何问题。达梦在兼容模式下部分版本只接受两个参数多参数的写法可能报参数个数错误。我的习惯是遇到需要拼接两个以上字段的地方直接用||运算符例如a || b || c这是达梦原生语法稳定可靠不需要考虑参数个数限制。空值处理上MySQL的IFNULL应用极广达梦主推Oracle风格的NVL好在兼容模式下IFNULL也能用。但有一个细节IFNULL和NVL在处理空字符串与NULL的语义在某些场景下不完全一致MySQL里空字符串和NULL是两种状态达梦同样区分可在具体SQL中要确认业务究竟想判断哪种状态。建议迁移时把IFNULL(x, )这类写法重新再过一遍业务逻辑不要想当然认为结果等价。2.3 标识符、大小写与特殊语句差异MySQL默认用反引号引用表名和字段名达梦的标准做法是双引号。看起来不过是一个符号的替换实际影响很大。达梦对加了双引号的标识符严格区分大小写不加双引号则统一按大写处理。这意味着原来MySQL里用反引号包起来的userName字段迁移到达梦后用双引号包住写userName才能匹配上如果直接写username达梦会当成全大写来匹配结果就是找不到列。我在项目里做了一个全局替换规则把MySQL的反引号替换成双引号但替换之后还要逐个检查原来字段是不是大小写混合命名混合命名的字段需要确认达梦侧的对象是否按大小写创建。最省事的办法是迁移阶段把所有表字段统一成大写或小写风格从源头避免大小写混乱。如果原系统里有大量驼峰命名字段这个改造量会比较大建议提前跟开发团队对一下命名改动的范围。特殊语句方面MySQL的INSERT ... ON DUPLICATE KEY UPDATE在达梦里没有对应语法需要改写成MERGE INTO。这是一个比较典型的看起来差不多、实际差很多的场景。MySQL里一行语句实现存在就更新不存在就插入达梦要用MERGE实现同样逻辑。提供一个改写示例-- MySQL 原写法 INSERT INTO t_user (id, name, age) VALUES (1, 张三, 20) ON DUPLICATE KEY UPDATE name 张三, age 20; -- 达梦改写 MERGE INTO t_user t USING (SELECT 1 AS id, 张三 AS name, 20 AS age FROM DUAL) s ON (t.id s.id) WHEN MATCHED THEN UPDATE SET t.name s.name, t.age s.age WHEN NOT MATCHED THEN INSERT (id, name, age) VALUES (s.id, s.name, s.age);REPLACE INTO也是MySQL常用语法达梦部分版本不直接支持同样建议用MERGE模式替代不要寄希望于兼容模式能兜住这类语句。还有UPDATE JOINMySQL支持UPDATE a JOIN b ON a.id b.id SET a.col b.col达梦不支持这种JOIN更新语法要改成子查询或MERGE。我在迁移报表模块时遇到过多处JOIN UPDATE全部手工改成了MERGE或相关子查询这部分没有捷径只能逐条处理。3. 语法兼容性改造实操3.1 表结构与DDL语句转换表结构迁移是第一步也是最容易批量处理的一步。DTS工具能自动生成达梦的建表语句但对数据类型映射不一定准确。我在实际项目里核对后发现MySQL的TINYINT(1)会被达梦映射成什么类型直接关系到后续程序读取布尔值的行为。关注几种关键类型DATETIME对应达梦的DATETIME一般没问题LONGTEXT在达梦里通常映射成CLOB读取方式有区别JSON类型达梦原生支持有限建议直接改成VARCHAR或CLOB存储原始JSON字符串由应用侧自己解析。还有一类MySQL特色类型需要特殊处理。ENUM和SET是MySQL独有的达梦没有对应类型迁移时要展开成VARCHAR加CHECK约束来保持合法性校验。如果原表里的ENUM取值列表很长CHECK约束的DDL会写得比较啰嗦但不建议省掉否则应用层对字段值的假设就失效了。掉进这个坑一次之后我的习惯是每个类型转换都写一条映射规则工具导完再对照检查一遍不能全信工具的默认映射。ALTER TABLE的语法也有一些差异。MySQL里修改列结构常写ALTER TABLE t MODIFY COLUMN name VARCHAR(200)达梦兼容模式下能不能识别其实不好说稳妥写法是ALTER TABLE t MODIFY name VARCHAR(200)去掉COLUMN关键字。删除列也一样MySQL写DROP COLUMN col达梦建议写DROP col。这些差异对人工SQL转换影响不大但如果你写了自动化转换脚本就需要注意关键字细节。另外一个DDL差异是修改自增列起始值MySQL用ALTER TABLE t AUTO_INCREMENT 100达梦要用ALTER TABLE t ALTER COLUMN id RESTART WITH 100这类命令不同版本命令形态有差异迁移后核实一下实际生效的写法。索引迁移相对简单MySQL的CREATE INDEX ... USING BTREE在达梦里去掉USING BTREE即可。需要注意索引命名冲突问题MySQL索引名在表内唯一达梦要求库内唯一甚至模式内唯一大库迁移时常遇到重名索引导致建索引失败。批量迁移前先在脚本里统一对索引名做一次重命名规划能省不少排查时间。3.2 处理SQL的等价改写数据加工SQL是语法改造的重灾区。我在某项目里把MySQL的报表SQL迁移到达梦十条里有六条要改其中最典型的是拼接和分组的改写。比如下面这条统计标签的SQL-- MySQL SELECT dept_id, GROUP_CONCAT(user_name ORDER BY id SEPARATOR ,) AS names FROM t_user GROUP BY dept_id;达梦改写为SELECT dept_id, LISTAGG(user_name, ,) WITHIN GROUP (ORDER BY id) AS names FROM t_user GROUP BY dept_id;LISTAGG的WITHIN GROUP里必须写清楚排序规则否则多个值的拼接顺序是乱的拼接结果虽然能出来但顺序不可控。第二种改写场景是正则匹配。MySQL用WHERE phone REGEXP ^1[0-9]{10}$达梦改写为WHERE REGEXP_LIKE(phone, ^1[0-9]{10}$)。第三种改写是子查询与连接条件的兼容问题。MySQL对派生表的要求相对宽松达梦对某些子查询的括号和别名要求更严格。遇到FROM (SELECT ...) t的写法个别情况下需要给派生表列加上别名或者用WITH子句重构。这类问题没有统一规律报什么错改什么但提前在代码里做一轮FROM (SELECT扫描能快速锁定可能出问题的SQL。还有一类容易被忽略的是布尔值判断的差别。MySQL的TINYINT字段可以直接WHERE flag 1达梦没问题但MySQL里有人习惯写WHERE flag来表示真值达梦不一定接受。这类隐含写法在Java代码拼SQL时比较常见用IDE或正则搜索WHERE [a-z_]后面不跟比较运算符的片段逐个确认补上 1或 0。3.3 存储过程、触发器与视图迁移存储过程是迁移里最费时间的对象因为两边语法风格差异太大。MySQL存储过程用DELIMITER切换结束符变量声明用DECLARE游标循环写WHILE ... DO。达梦的存储过程更接近Oracle风格参数支持IN/OUT/INOUT主体结构用AS加BEGIN...END异常处理使用EXCEPTION WHEN ... THEN。编列一个最典型的游标循环两边的写法差异一目了然。MySQL的游标循环通常在DECLARE CONTINUE HANDLER FOR NOT FOUND SET done TRUE后配合REPEAT...UNTIL。达梦要改成类似Oracle的FOR ... IN 游标 LOOP ... END LOOP或者用OPEN 游标加FETCH ... INTO手动循环。更省心的方案是把小逻辑写在视图里用纯SQL取代部分存储过程。某项目里我们迁移了二十多个存储过程其中三分之一可以改写成视图或临时表加工来实现剩下才真正需要保留过程逻辑。触发器迁移也有几个坑。MySQL的CREATE TRIGGER trg BEFORE INSERT ON t FOR EACH ROW到达梦后需要加REFERENCING NEW ROW AS new之类的子句才能在新行引用里使用:NEW.col或new.col。这里新旧记录引用的写法差异极其容易踩坑达梦兼容MySQL的NEW.col写法时有时需要声明引用名不声明就直接用会导致编译失败。触发器里如果调用了存储过程或函数这些被调对象必须先迁移并编译通过否则触发器创建时报错。视图迁移相对简单主要是内部SELECT语句的语法兼容。达梦支持CREATE OR REPLACE VIEWMySQL也支持结构上没问题。视图里如果用了GROUP_CONCAT、DATE_FORMAT这类函数按前面列出的映射关系逐项替换。视图迁移还有个细节达梦视图内ORDER BY子句在部分场景下不允许出现MySQL里写了ORDER BY的视图要提前去掉把排序放到查询侧。4. 完整迁移流程与数据校验4.1 迁移工具的配置与数据导入实操DTS工具是达梦官方的图形化数据迁移工具整体流程是新建工程选择源库类型为MySQL填入IP地址、端口、数据库名、账号密码再配置目标库连接选择达梦库和模式。连接测试通过后选择需要迁移的对象。这里建议不要一次性勾选全部表尤其当对象列表里有几百张表时迁移工具生成的映射一旦出错很难定位到具体是哪张表导致的失败。我习惯按业务模块分批次迁移每批三五十张表失败时日志定位也比较快。大表处理是迁移过程中的核心问题。DTS工具迁移本质上也是通过JDBC读取源库再写入目标库一次性读取超大表容易内存溢出或超时。工具里一般有每次读取行数或批量提交行数这类参数我调成5000到10000行一个批次。实测下来批量值太小导入速度慢太大容易造成目标库侧锁竞争或内存压力。对亿级大表还可以考虑按主键范围拆成多个查询片段在工具配置里用查询语句限定WHERE条件来分批抽取相当于把一张大表拆成多段导入。数据导入中途失败是常见现象千万不用急着从头再来。DTS工具一般支持断点或从失败任务恢复如果没有恢复功能建议在导入前做好记录知道已成功迁到哪一批。我遇到过的情况是导到一半报唯一约束冲突排查后发现问题出在源库本身存在重复数据而目标表建了唯一索引。这种问题属于源库数据质量问题迁移工具不管需要先在MySQL里清理重复数据再继续导。LOB字段是另一个性能瓶颈。包含TEXT、CLOB字段的表DTS在导入时如果字段内容很大单条记录可能占用很多内存。大字段建议单独拆出来处理比如迁移时先跳过LOB列只导普通字段再用一个专用程序按主键批量补全LOB内容。常规业务表很少需要这么折腾但内容管理类系统里的文本字段特别大分批补全比一次到位稳得多。4.2 迁移后的数据校验与自增序列修复数据迁完不能直接宣布成功我自用的校验方案是过三关。第一关行数对比逐表执行SELECT COUNT(*)MySQL和达梦各跑一遍数字对不上就直接定位于迁移失败的表。第二关主键与唯一键重复校验很多迁移工具遇到源库脏数据时为了避免报错会降级处理导致目标库出现重复记录单独跑一遍SELECT id, COUNT(*) FROM t GROUP BY id HAVING COUNT(*) 1排查。第三关抽样数据比对对每张表抽几条关键字段做对比。抽样比对时间字段时要特别留意时区和精度。MySQL的DATETIME默认不包含时区达梦的TIMESTAMP精度可以到微秒级如果原字段存了毫秒或微秒值迁移后显示格式会不一样。金额字段也要抽查几位小数确认DECIMAL(p,s)映射没有精度丢失。我在某项目上发现金额字段被工具默认映射成DECIMAL(18,0)直接把小数位全截掉了这种问题只有通过抽样比对才能发现。自增列修复是上线前最容易被遗漏的一步。DTS迁移数据时如果目标表用了IDENTITY列数据导入并不会同步更新自增序列的下一个起点。表现为老数据都正常应用插入新数据时报主键冲突。修复方式通常在达梦侧执行类似ALTER TABLE t ALTER COLUMN id RESTART WITH n的语句n为当前最大ID加1。不同达梦版本具体命令有差异但思路一致上线前务必检查每张含自增列的表把它下一个自增值调整到位。5. 应用层适配与性能调优5.1 JDBC驱动、连接池与ORM方言配置数据库换了应用层的数据源配置必须同步改。首先是JDBC驱动MySQL用com.mysql.cj.jdbc.Driver达梦用dm.jdbc.driver.DmDriver连接URL前缀从jdbc:mysql://改成jdbc:dm://。端口也要改MySQL一般是3306达梦默认是5236。这个改动本身不难但很多项目改了连接配置之后发现程序里还散落着MySQL驱动的类名引用所以改配置后要把项目全局搜索一遍把mysql-connector相关的依赖和类引用清理干净。连接池方面Druid和HikariCP都能适配达梦的JDBC驱动需要注意的一点是驱动类名要配正确否则连接池测试连接时报无法找到驱动。MyBatis本身没有方言概念SQL兼容性问题都留在Mapper XML里处理所以前面第二、第三节讲的语法改造很大一部分最终要落到XML文件里逐一修改。Hibernate不同它依赖方言配置生成SQL达梦提供了自己的方言类配置类似hibernate.dialectdm.Dialect或org.hibernate.dialect.DmDialect具体类名看所用达梦驱动版本配错方言会导致分页SQL自动生成出错。应用层还有一种情况是代码里直接拼SQL比如通过JDBC的Statement执行动态查询。这类SQL不受ORM管理排查时必须全局搜索Statement和createNativeQuery出现的位置把拼在Java代码里的SQL拉出来逐条过语法。这是整个迁移计划里最容易被低估的工作量我在项目里沟通排期时开发团队说我们的SQL都用MyBatis管理扫完代码才发现还有好几十处原生JDBC调用。5.2 应用SQL排查与执行计划优化应用层SQL排查的目标只有一个找出所有MySQL方言写法的SQL。我建议写几个正则批量扫描代码仓库比如搜\\LIMIT\\s\\?\\s*,\\s*\\?匹配两参数分页搜ON DUPLICATE KEY UPDATE匹配特殊语法搜GROUP_CONCAT\\(匹配聚合拼接。这一轮下来基本能把高风险SQL圈出来。还有一个技巧把达梦数据库的SQL日志打开上线前让测试环境跑一遍完整回归达梦会打印所有实际执行SQL把日志里执行失败的语句全部捞出来逐条修复比人工扫代码更全面。性能问题往往在数据量上去之后才会暴露。迁移完成初期原来MySQL里跑得飞快的SQL到了达梦上可能变慢。优先检查统计信息是否已刷新。达梦支持DBMS_STATS包迁移后立刻执行统计信息收集语句类似DBMS_STATS.GATHER_SCHEMA_STATS(你的模式名, cascade TRUE);不刷统计信息的情况下优化器拿不到表数据分布很可能选错执行计划导致全表扫描。我的实际经验是刚迁完环境上遇到的慢SQL一半以上可以通过刷新统计信息解决。另一半是SQL本身在达梦侧无法走索引。常见原因是隐式类型转换。比如字段是VARCHAR应用侧传数字类型MySQL会隐式转换但不影响索引使用达梦有时候就不会走索引。这种情况要在应用SQL里把参数类型写明确该加引号加引号。还有一种情况是函数包裹索引列比如WHERE TO_CHAR(create_time, YYYY-MM-DD) 2025-01-01这种写法在两边都不容易走索引需要改写成范围查询create_time 2025-01-01 AND create_time 2025-01-02改写后两边执行效率都正常。达梦提供EXPLAIN查看执行计划和MySQL的使用方式类似在SQL前面加EXPLAIN关键字就能看到执行路径。排查慢SQL时重点看有没有全表扫描、有没有走错索引、连接顺序是否合理。遇到连接顺序问题可以尝试调整表连接顺序或者加优化器提示。这个环节本质上和一般的数据库性能调优没有太大区别只是把工具从熟悉的MySQL命令换成了达梦的命令思路是通用的。6. 常见问题排查速查表6.1 迁移期高频报错归纳把迁移过程中最常见的报错和解决办法整理成速查表方便直接对号入座现象可能原因处理方式迁移工具连不上MySQL驱动缺失或MySQL端未开放远程访问把mysql-connector-java.jar放进DTS驱动目录检查MySQL账号权限报语法错误 near LIMIT两参数LIMIT写法改为LIMIT ? OFFSET ?表名或字段名找不到大小写敏感或引号问题确认对象实际大小写用双引号包裹引用导入中文乱码字符集不一致统一源库与目标库的字符集设置导入前确认连接参数自增列插入新数据主键冲突IDENTITY起始值未复位执行RESTART WITH语法调整自增起点存储过程编译失败游标或异常语法不兼容按Oracle风格改写游标与EXCEPTION块JSON字段无法建表MySQL JSON类型无对应改为CLOB或VARCHAR应用层自行解析LIMIT报错和表名大小写问题在上线前扫一遍就能发现建议把这类检查做成一个静态检查脚本。字符集乱码问题最怕数据导入后才暴露一旦数据已经进去再修改字符集就意味着重新迁移一遍。我在项目里的做法是先用十张左右的小表做一次全流程试迁移把字符集、类型映射、自增列、分页全部验证一遍确认没问题再开始全量迁移。存储过程编译失败要单独高度重视因为它失败之后会连带触发器一起失败如果触发器没有编译成功数据写入行为可能不一致。我的建议是迁移脚本里把函数、存储过程、触发器按依赖顺序分别编译报错信息逐条记录不要一口气执行几十个脚本然后只看最终成功数量。某项目里你遇到的最棘手存储过程问题往往是运行时才报错而不是编译时报错编译期成功但执行期因为某个函数不存在导致过程直接回滚这类问题只能依靠覆盖完整的业务回归来兜底。6.2 上线后典型问题与避坑心得上线之后最常见的问题是数据库连接报错和性能异常。连接报错里很多是驱动版本不匹配或者URL参数写法不兼容比如达梦驱动对useSSL、characterEncoding这类MySQL连接参数的容忍度有限多余的参数可能导致连接建立失败。连接池配置里建议把MySQL专属参数全部去掉只保留达梦识别的基础参数否则排查起来很费劲。性能异常方面上线初期可以先观察一段时间的慢SQL日志把执行时间超过阈值的新增SQL捞出来。我发现迁移后慢SQL往往不是原来就慢的而是原来在MySQL里走了正确索引、到达梦后因为统计信息缺失或隐式类型转换走了全表扫描。处理手段就是刷新统计信息、明确参数类型、改写函数包裹列三件套做完大部分慢SQL能恢复正常。最后说一个避坑心得迁移项目最忌讳把数据库切换当成一个搬家动作更准确地说这是一次完整的应用兼容性改造。我在项目里把节奏拆成三阶段先完成表结构和数据迁移再完成应用层SQL改造和测试最后做性能对比和上线。每个阶段的验收标准都提前约定好比如行数一致、核心接口响应时间与迁移前差异不超过20%。把标准定在前面后面推进起来就不会出现上线了才发现报表SQL跑不出来的情况。个人体会我在实际项目里最深的体会就是MySQL迁移达梦数据库数据迁移工具能帮你解决量的问题但SQL语法兼容才是决定项目成败的关键。做迁移方案时不要一上来就研究工具怎么用先把所有存储过程和业务SQL摸底一遍评估出语法改造工作量再安排整体计划。如果你也是第一次做这类迁移建议拿一个相对独立的业务模块先试点跑通全流程摸清坑点再铺开到全量。这样踩坑的成本最低团队信心也能在试点成功之后建立起来。另外一个值得后续扩展的方向是把每个迁移脚本固化成可复用的检查清单包括对象清单、类型映射表、函数对照表、分页改写规则、校验SQL和自增序列修复命令。这次项目里我费了不少精力重新整理这些内容下一步可以直接沉淀成一套半自动化的迁移辅助脚本以后再有同类迁移先在几分钟内跑一遍语法体检对工作量做到心里有数。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑