我的表的某些列需要支持 Unicode 字符(假设是我所有列的 1%)。
我想我有以下两个选择:
- 将 Unicode 列实现为NVARCHAR2;或者
- 将整个数据库的字符集更改为支持 Unicode 的字符集(这样我可以使用VARCHAR2)。
我倾向于第二种选择(为了不必更改我已经存在的 VARCHAR2 脚本)。
我的问题是:与第一个选项相比,第二个选项的缺点和优点是什么?它的性能更低吗?
我的表的某些列需要支持 Unicode 字符(假设是我所有列的 1%)。
我想我有以下两个选择:
我倾向于第二种选择(为了不必更改我已经存在的 VARCHAR2 脚本)。
我的问题是:与第一个选项相比,第二个选项的缺点和优点是什么?它的性能更低吗?
我强烈倾向于更改数据库的字符集。
这样做有潜在的弊端
VARCHAR2
. 默认情况下,VARCHAR2(50)
分配 50 个字节的存储空间,如果您使用的是 AL32UTF8 字符集,则可以存储 16 到 50 个字符,而不是像使用单字节字符时那样进行简单的 1:1 映射放。这将需要您增加列的大小(即三倍)以确保它们存储适当数量的字符,或者您在声明列时指定字符长度语义(即VARCHAR2(50 CHAR)
)或您将您设置NLS_LENGTH_SEMANTICS
为CHAR
之前创建对象以将默认值更改为字符长度语义。甲骨文全球化论坛上有讨论是否适合在实例级别更改 NLS_LENGTH_SEMANTICS -- Oracle 的顶级全球化专家之一 Sergiusz Wolicki 强烈反对它,尽管我个人更愿意在适当的情况下考虑它。您还可以NLS_LENGTH_SEMANTICS
在会话级别设置,这是 Sergiusz 不反对但确实要求您在每次运行脚本时都这样做,这可能是一个问题。CHAR_LENGTH
和DATA_LENGTH
列,他们想要字符长度与字节长度。如果您有现有的工具/脚本/等对数据字典运行查询以生成 DDL 或确定需要分配多少内存或您最终会遇到的其他情况,这对您来说可能是一个小问题或一个严重的痛苦得到时髦的结果。但是,为所有数据使用单一字符集的优势远远超过了这些缺点
NVARCHAR2
列通常需要更改应用程序代码。由于您将同时拥有VARCHAR2
和NVARCHAR2
列,因此这些代码更改和配置设置可能很重要,并且通常是一个主要的烦恼。不可避免地,您会发现在某些应用程序中错误地映射了特定列,并且您会遇到难以追踪的数据损坏错误。数据库和应用程序之间的抽象层越多,这一点就越真实。VARCHAR2
更改为NVARCHAR2
是一件痛苦的事情——您需要添加一个新列,复制数据,删除旧列,重命名新列,并处理导致的行迁移。然后,您必须对所有现有应用程序进行更改,以便它们正确映射列。当企业决定再增加一列以支持其他语言并且您的数据库和应用程序已经支持 Unicode 时,这种努力和测试水平似乎相当过分。NVARCHAR2
在应用程序中将列中的数据用作 SQL 语句中的文字(例如,避免绑定变量窥视或更好地利用直方图)或在需要时作为生产支持的一部分,这往往会产生问题跟踪数据中的问题。NVARCHAR2
列。这可能不会立即产生实际后果,但如果您的系统应该存在多年,那么将来很可能会产生后果。Sergiusz 在此线程中很好地总结了 Oracle 的建议
甲骨文的建议:
- 对于任何新数据库,使用 AL32UTF8 字符集创建它并忘记 NCHAR 数据类型。
- 对于要制作多语言的任何现有应用程序,请将后端数据库迁移到 AL32UTF8 并忘记 NCHAR 数据类型。
- 对于为大型遗留应用程序系统提供服务的任何现有非 Unicode 数据库,成本太高或无法迁移到 Unicode,您被要求添加一个必须支持多语言数据的次要模块,并且单独的数据库没有多大意义,对于这种多语言数据,您可以考虑使用 NVARCHAR2 列。