oracle19C(ZHS16GBK - 简体中文字符集) 数据库迁移到 oracle19C(AL32UTF8 - Unicode字符集)数据库方案
背景
系统一直使用的oracle19C(ZHS16GBK - 简体中文字符集) 版本,项目上由于多个产品线共用一个数据库实例,其他产品都是oracle19C(AL32UTF8 - Unicode字符集),如果使用impdp导入 gbk编码的dmp文件,由于gbk一个中文占用两个字节、utf8一个中文占用3个字节,导入过程会有大量会报错数据截断错误。
ZHS16GBK AL32UTF8字符集介绍
ZHS16GBK - 简体中文字符集 介绍
编码结构:
扩展GB2312标准,支持21003个汉字
双字节编码(0x8140-0xFEFE)
兼容ASCII(0x00-0x7F单字节)
字符范围:
简体中文(GB 18030-2000基本集)
常见繁体字
中文标点符号(全角)
部分日文假名和特殊符号
局限性:
不支持越南语、泰语等东南亚文字
部分生僻字可能无法显示
AL32UTF8 - Unicode字符集
核心优势:
完整Unicode支持(最新版本)
可变长度编码(1-4字节/字符)
兼容所有语言字符
编码方式:
ASCII字符:1字节(0x00-0x7F)
欧洲文字:通常2字节(如é: 0xC3A9)
中文/日文/韩文:通常3字节(中: 0xE4B8AD)
特殊符号/罕见字:4字节
数据库迁移方案
从utf8编码存储,一个中文占用3个字节,gbk占用两个字节编码入手,把数据库指定用户下所有的varchar、char字段加长1.5倍,如果加长1.5倍后长度大于4000,则最大取4000,因oracle数据库最大长度只支持4000,如果数据库里的内容已经超过大小导入时只有截断,后面换成clob字段单独处理;
另外我还考虑到一个问题,char是固定长度类型,如故char增加1.5倍长度,会导致存储的内容增加空格补足,很多程序查询数据库char字段没做处理,查询到的数据会带很多空格,所以我是想到批量把该用户下所有char字段先改为varchar字段。
迁移步骤
一、先把数据库指定用户导出,重新创建表空间、用户导入到数据库实例,如果直接在开发数据库操作,出问题比较麻烦
从10.19.40.40 导出门户和体检库
# 表空间 BBPNEW_SPACE
expdp C##BBPNEW/Bsoft123 schemas=C##BBPNEW dumpfile=20250614BBPNEW.dmp # 表空间 CYTJ410_SPACE
expdp C##BBP402CYTJDEV41/Bsoft123 schemas=C##BBP402CYTJDEV41 dumpfile=20250614BBP402CYTJDEV41.dmp
创建C##BBPNEWSTD,C##BBP402CYTJDEV41STD用户,BBPNEW_SPACE_STD,CYTJ410_SPACE_STD表空间
表空间、用户名 加STD为标准的含义
# 创建bbp表空间用户
CREATE TABLESPACE BBPNEW_SPACE_STD
DATAFILE '/data/oradata/BBPNEW_SPACE_STD.dbf'SIZE