我的表的某些列需要支持 Unicode 字符(假设 我所有列的 1% )。
我想我有以下两个选择:
我倾向于第二个选项(为了不必更改我已经存在的 VARCHAR2 脚本)。
我的问题是:什么是 优缺点与第一个选项相比,第二个选项如何?它的性能较低吗?
最佳答案
我强烈倾向于更改数据库的字符集。
这样做有潜在的缺点
VARCHAR2
时,您必须关心字符与字节语义。 .默认情况下,VARCHAR2(50)
如果您使用的是 AL32UTF8 字符集,而不是像使用单字节字符集那样是简单的 1:1 映射,则分配 50 字节的存储空间,这将允许您存储 16 到 50 个字符。这将要求您增加列的大小(即三倍)以确保它们存储适当数量的字符,或者在声明列时指定字符长度语义(即 VARCHAR2(50 CHAR)
)或您设置您的 NLS_LENGTH_SEMANTICS
至 CHAR
在创建对象以将默认值更改为字符长度语义之前。 Oracle全局化论坛上有讨论是否适合change the NLS_LENGTH_SEMANTICS at the instance level ——甲骨文的顶级全局化大师之一 Sergiusz Wolicki 强烈反对它,尽管我个人更愿意在适当的情况下考虑它。您也可以设置 NLS_LENGTH_SEMANTICS
在 session 级别,Sergiusz 不反对,但要求您每次运行脚本时都这样做,这可能是一个问题。 CHAR_LENGTH
和 DATA_LENGTH
他们想要以字符为单位的长度与以字节为单位的长度的列。这对您来说可能是一个小问题,或者如果您有现有的工具/脚本/等对数据字典运行查询以生成 DDL 或确定需要分配多少内存或其他一些您最终会遇到的情况得到时髦的结果。 但是,所有数据使用单个字符集的优势远远超过了这些缺点
NVARCHAR2
列通常需要更改应用程序代码。由于您将同时拥有 VARCHAR2
和 NVARCHAR2
列,这些代码更改和配置设置可能非常重要,并且通常是一个主要的烦恼。不可避免地,您会发现在某些应用程序中错误地映射了特定列,并且会遇到难以追踪的数据损坏错误。数据库和应用程序之间的抽象层越多,这一点就越正确。 VARCHAR2
更改为至 NVARCHAR2
很痛苦——你需要添加一个新列,复制数据,删除旧列,重命名新列,并处理由此产生的行迁移。然后,您必须对所有现有应用程序进行更改,以便它们正确映射列。当企业决定需要再增加一个列来支持其他语言并且您的数据库和应用程序已经支持 Unicode 时,这种级别的努力和测试似乎相当过分。 NVARCHAR2
的数据,这往往会产生问题。列作为 SQL 语句中的文字在应用程序中(例如,避免绑定(bind)变量窥视或更好地利用直方图)或作为生产支持的一部分,当您想要跟踪数据中的问题时。 NVARCHAR2
的使用强烈建议不要使用列。这可能不会立即产生实际后果,但如果您的系统应该存在数年,那么将来很可能会产生后果。 Sergiusz 在 this thread 中很好地总结了 Oracle 的建议
Oracle's advice:
- For any new database, create it with the AL32UTF8 character set and forget about NCHAR data types.
- For any existing application to be made multilingual, migrate the backend database to AL32UTF8 and forget about NCHAR data types.
- For any existing non-Unicode database serving a large legacy application system that is too costly or impossible to migrate to Unicode, to which you are asked to add a minor module that has to support multilingual data and for which a separate database makes little sense, you may consider NVARCHAR2 columns for this multilingual data.
关于database - 将整个 DB 字符集设置为 Unicode 的缺点与 Oracle DB 中的某些 NVARCHAR2 相比?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12801207/