选AL32UTF8是最稳妥方案,因其完整支持Unicode代理对、emoji及多语言字符;ZHS16GBK虽中文省空间但不支持生僻字和外部系统对接;UTF8已被Oracle弃用且不支持代理对。

选 AL32UTF8 是当前最稳妥的通用方案,除非你明确只跑纯中文、且对存储空间极度敏感、且不涉及任何外部系统对接。
AL32UTF8 vs ZHS16GBK:中文场景下到底差在哪
ZHS16GBK 看似“省空间”——中文固定 2 字节,但代价是:不支持生僻字(如“䶮”“堃”)、不支持 emoji、不支持越南文/日文/韩文混合字段;一旦业务扩展或对接第三方 API(比如微信、钉钉、海外支付),立刻触发乱码或 ORA-12704 错误。
AL32UTF8 中文占 3 字节,和 UTF8 表面一样,但关键区别在于:它完整支持 Unicode 代理对(surrogate pairs),能正确存取 emoji 和所有 Unicode 6.2+ 字符;ZHS16GBK 根本无法解析这些字节,直接截断或转成 。
- 已有系统用 ZHS16GBK?别硬切——先评估存量数据是否含扩展汉字(查
V$NLS_PARAMETERS+SELECT DUMP(column_name) FROM table WHERE ...看高位字节) - 新库一律跳过 ZHS16GBK,除非你签了 SLA 要求“每 TB 存储节省 33%”,且法务确认不碰多语言数据
-
NLS_NCHAR_CHARACTERSET必须配AL16UTF16,这是 Oracle 对NCHAR/NCLOB的强制要求,别手抖改成 UTF8
为什么不能选 UTF8 字符集
Oracle 从 11g 起就把 UTF8 标为 deprecated,不是警告,是明确弃用。它基于旧版 Unicode 3.0,不支持代理对,遇到 emoji 或某些中日韩扩展区字符会静默丢字或报 ORA-12712。
DBCA 界面里那个 Use national character set (UTF8) 选项,名字有误导性——它指的不是数据库主字符集,而是 NCHAR 的后备选项,且已不推荐。真正该勾的是 Use Unicode (AL32UTF8)。
- 执行
SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_CHARACTERSET',返回UTF8就得警惕:这不是“兼容模式”,是技术债 - 迁移时若看到脚本里写
CHARACTERSET UTF8,必须手动替换成AL32UTF8 - 客户端
NLS_LANG设成.UTF8也不行——NLS_LANG=AMERICAN_AMERICA.AL32UTF8才合法
建库时 DBA 最容易漏掉的三个动作
DBCA 默认隐藏字符集配置页,尤其在 Typical install 模式下。很多人一路 Next,结果字符集落到操作系统 locale(Windows 常是 WE8MSWIN1252,Linux 可能是 ZHS16GBK),后续改就是灾难。
- 必须切到
Advanced install模式,否则Character Sets页面根本不出现在向导流程里 - 在
Character Sets页,只勾Use Unicode (AL32UTF8)——另一个选项Use national character set (UTF8)不要碰 - 勾完后检查生成的建库脚本(通常在
$ORACLE_BASE/cfgtoollogs/dbca/<dbname>/下),确认含CHARACTERSET AL32UTF8和NATIONAL CHARACTER SET AL16UTF16两行
字符集不是装完就完的事——它绑定了数据字典初始化时的所有元数据解释逻辑。哪怕你只是想让一个字段存 emoji,只要数据库字符集不是 AL32UTF8,INSERT INTO t VALUES ('??') 就可能变成乱码或报错。别信“后期再改”,ORA-12712 不是 bug,是 Oracle 在拦你跳坑。


















