前言
好记性不如烂笔头,就算是自己做过的东西,时间久了也会有些模糊。刚开始写这篇文章的时候才刚开始,经过一个春节,现在基本收尾。所以想完整地梳理和记录一下迁移过程中碰到的问题,不谈业务逻辑,仅作个人小结用(不涉及任何项目细节)
参考内容随文附上。如有错误之处,欢迎指正。
正文
大致梳理一下迁移过程中涉及到的部分,分模块慢慢整理更新。
想了很久不知道怎么安排行文,最开始只是为了记录我在做自己那部分时遇到的问题,后来把整个流程跟了下来,又想把整个流程形成案例分享,这样的话,扩展出去的东西就太多了(每一个扩展的知识点深入理解学习,展开讲讲都够一篇博文的)……
一、准备工作
分Sheet整理出Oracle数据库中涉及到的全部表、视图、物化视图、存储过程、触发器、函数、定时任务、涉及业务改造迁移(略)。
这样有几个好处:
- 方便团队分工
- 便于进度反馈和跟踪
- 保证测试验证的有序
- 确保迁移的完整性
做好生产环境和测试环境的一致性确认,做好数据库安全基线的检查。这方面已经吃过亏了,谨记!
讨论迁移过程中可能出现的问题及解决方案,比如MySQL没有物化视图的概念,如何实现?比如相对Oracle而言,存储过程不适合在MySQL实现,如何落地转换?比如MySQL不存在dblink的功能。比如,可能产生的查询效率低下,对查询实时性的要求等等……
最后确定时间节点。
二、表结构迁移
主要是字段类型的不同,以及对字符集、排序规则和Unicode编码的配置。
Oracle | MySQL |
varchar2 | varchar |
number | int/bigint/decimal() |
date | datetime |
enable | 空 |
两个问题:
- 字段长度超过3072的无法建立索引
- 全部表字段总长度超过65535的无法建表
针对以上两个问题,考虑把varchar(4000)等长字段类型视情况改为text/longtext/blob等类型规避解决。
针对字符集编码为utf8mb4,核对码为utf8mb4_general_ci。在后面验证迁移数据是否一致性的时候才发现一个大坑。
部分视图刷新以后的数据量差了几条到十几条不等,单看逻辑没有任何问题,实在不知道从何下手,选了个表数据在一百条左右的,把Oracle和MySQL拉出来比对,发现对涉及到中英文括号的,MySQL中自动视为一条。对另外出现同样问题的表检查均为对大小写、中英文的敏感导致的数据量差异。把涉及核对码改为utf8mb4_general_bin后解决,(存个疑问:针对统一表中存在不同核对码是否会影响数据库操作,目前没发现)。
拓展一:数据库约束
enable这个字段转换的时候直接跳过了,设为空。
其实并不非常理解,查到是用于控制约束,控制表的约束是禁止还是激活状态。
disable:禁止状态,相当于该列没有约束,使用disable默认为Novalidate
enable:激活状态,默认新创建的约束状态是激活状态,使用enable默认为Validate
有一种说法:enable和disable是对未来数据的约束。这里拓展一下,谈谈数据库的约束。
比较常见和常用的四种约束:主键约束(primary key)[相当于unique+not null]、唯一性约束(unique)、非空约束(not null)、外键约束(foreign key)
还有一种对我而言比较新鲜的:检查约束(check)
参考文献一中提到:
很多时候由于业务需要,比如我们有大量的历史数据,需要和现有数据合并,当前表存在数据库约束(如非空约束),而这些历史数据又包含违背非空约束的数据行,为了避免导入时由于违反约束而导入失败,我们通过调整约束状态来达到目的。
数据库约束有两类状态
启用/禁用(enable/disable):是否对新变更的数据启用约束验证
验证/非验证 (validate/novalidate) :是否对表中已客观存在的数据进行约束验证
这两类四种状态从语法角度讲可以随意组合,默认是 enable validate
我们需要上传大量违反非空约束的历史数据(从业务角度讲这些数据不会造成系统功能异常),可以临时将约束状态转为 disable novalidate,以保证这些不合要求的数据导入表中
alter table emp modify constraint emp_ename_nn disable novalidate;在数据导入完成之后,我们再将约束状态转为enable novalidate 以确保之后添加的数据不会再违反约束
alter table emp m