异构数据库迁移埋下的 9 个大坑,你怎么还不会躲开?( 二 )


跨数据库的表字段数据类型转换工作主要涉及“精度”、“效率”、以及“兼容性”等方面 。 部分数据同步软件确实具备自动转换的功能 , 然而这种情况 , 仅对于管理规范的数据库适用 , 不规范的库则需要耗费较大精力了 , 下面举几个典型的例子说明这个问题:

  • 以从Oracle DB到PG的同步为例 , 整型的值固然可以通过number类型(不设定精度和小数位)存放到源端Oracle数据库中 , 问题来了 , PG中应该用啥字段对应了 , 仅仅安全起见 , 免得精度丢失 , 那肯定是numeric类型 , 然而这毫无疑问存在性能损失 。 Bigint等类型自然是更好的选择 , 可是这又牵涉到与开发商沟通这样有没有可能导致应用报错等情况了 , 这又是一个工作量 。
  • 以从Oracle DB到DB2的同步为例 , DB2有一个隐性要求 , 组成主键的字段值前后不能包含空格 , 否则会被过滤掉 , 这样会造成一些在源端Oracle数据库本来就不相同的两条记录的在目标端DB2库被误判为同一条记录进而引发数据冲突 , 影响数据同步 。
不要问为什么要在id类字段加空格:第一 , 这是合法的;第二 , 这未尝不是一种有创意的备份数据方法 。 这么干 , 真的 , 没毛病!
  • 以从Oracle DB到ADB的同步为例 , 由于MPP架构需要 , 我们需要额外指定DISTRIBUTED列 。 对于ADB而言 , 这里还有一个附带的要求 , 这个列应当为主键的一部分 。
  • 以Oracle DB到HBase的同步为例 , HBase是强制要求有主键的 , 否则不能同步 。 之前的项目中 , 笔者被迫无奈拿Oracle的转换后的ROWID作为HBase的rowkey , 满足其同步前置条件 。
为什么是转换后?这又是另一个故事了 , 这里就不展开了 , 只提示个关键词 , “预分区” 。
嗯嗯 , 这明显是个坑 。 那种由开发商定表结构的项目得心存感激 , 真的!
三、字符集转换问题
字符集转换深究起来其实并不是容易的事情 , 几年前笔者所参与的一个O2O同步(即Oracle到Oracle的同步 , 下同) 迁移项目中 , 涉及了BIG5到UTF8的转换 , 当时的同步工具为OGG 。 这个项目中各种乱七八糟的数据至今仍然对笔者历历在目 , 当然 , 这也让笔者能更有经验地处理异构数据库同步中的字符集转换问题 。
跨字符集转换的工作其实陷阱不少 , 因此 , 条件允许的话 , 笔者建议尽量规避 。 当然 , 遇到PG这种服务器端不支持GBK , 而源端Oracle DB偏偏是GBK的情况 , 那只好迎难而上了 , 下面为笔者的建议:
  • 涉及中文的情况 , 所见非所得 , 判断一条中文记录是否正常的依据 , 应该为其十六进制编码是否正常 。 对于Oracle DB而言 , 我们可以用dump函数 , 其余DB需要找到类似的 。
  • 中文为多字节字符 , 在不同的字符集下占用的字节数并不一致 , 典型例子为GBK为2字节 , UTF8为3字节 。 目标端环境可能需要相应调整字节宽度 。
  • 不同字符集所涵盖的汉字是不一样的 , 例如BIG5中就没有“邨”字 。
  • 字符集中有一个“自定义”区域 , 如不进行特殊处理 , 有可能导致数据丢失 。
  • “乱码”会造成很大的困扰 , 对于Oracle DB而言 , 大致有如下几种情况:
  • 无法通过Oracle自带convert函数转换为目标库编码 , 以ADB为例 , 这部分数据会导致GPFDIST导入失败 , 进而影响数据全量同步 。
  • 可以通过Oracle自带convert函数转换为目标库编码 , 但无法重新转换为原有数据 , 这部分数据会有潜在的数据丢失影响 , 对于迁移类项目需要重点关注是否涉及“自定义”字符区域 。
  • 含义不明的单字节字符 , 如chr(0)、chr(255) , 这些字符往往夹杂在正常的字符中 , 以ADB为例 , 涉及dts( Data Transmission Service ,数据传输服务 , 系阿里的数据同步工具/服务)增量同步的话 , 相应记录有数据一致性风险 。

    特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。