database - 将整个 DB 字符集设置为 Unicode 的缺点与 Oracle DB 中的某些 NVARCHAR2 相比?

标签 database oracle database-design unicode oracle11g

我的表的某些列需要支持 Unicode 字符(假设 我所有列的 1% )。

我想我有以下两个选择:

  • 将 Unicode 列实现为 NVARCHAR2 ;或
  • 将整个数据库的字符集更改为支持 Unicode 的字符集(这样我可以使用 VARCHAR2 )。

  • 我倾向于第二个选项(为了不必更改我已经存在的 VARCHAR2 脚本)。

    我的问题是:什么是 优缺点与第一个选项相比,第二个选项如何?它的性能较低吗?

    最佳答案

    我强烈倾向于更改数据库的字符集。

    这样做有潜在的缺点

  • 如果您在其他列中存储的数据不在 7 位 ASCII 字符集中,您将增加存储数据所需的空间量。假设您现有的字符集是允许您存储英语和其他几种语言的 8 位字符集之一,则数据中的任何非英语字符通常每个字符需要 2 个或更多字节的存储空间。例如,如果您要存储字符“h”,它是一个英文字符,它是 7 位 ASCII 字符集的一部分,因此在您的单字节字符集或 Unicode 字符集中需要 1 个字节。另一方面,如果您要存储字符“À”,则该字符不是英语,也不是 7 位 ASCII 字符集的一部分,因此在 Unicode 字符集中需要 2 个字节的存储空间,而在现有字符集中需要 1 个字节的存储空间单字节字符集。其他字符将需要 3 个字节的存储空间。
  • 当您声明 VARCHAR2 时,您必须关心字符与字节语义。 .默认情况下,VARCHAR2(50)如果您使用的是 AL32UTF8 字符集,而不是像使用单字节字符集那样是简单的 1:1 映射,则分配 50 字节的存储空间,这将允许您存储 16 到 50 个字符。这将要求您增加列的大小(即三倍)以确保它们存储适当数量的字符,或者在声明列时指定字符长度语义(即 VARCHAR2(50 CHAR) )或您设置您的 NLS_LENGTH_SEMANTICSCHAR在创建对象以将默认值更改为字符长度语义之前。 Oracle全局化论坛上有讨论是否适合change the NLS_LENGTH_SEMANTICS at the instance level ——甲骨文的顶级全局化大师之一 Sergiusz Wolicki 强烈反对它,尽管我个人更愿意在适当的情况下考虑它。您也可以设置 NLS_LENGTH_SEMANTICS在 session 级别,Sergiusz 不反对,但要求您每次运行脚本时都这样做,这可能是一个问题。
  • 大多数工具不能很好地处理针对数据字典的查询,其中使用字符语义来创建列。他们没有正确使用 CHAR_LENGTHDATA_LENGTH他们想要以字符为单位的长度与以字节为单位的长度的列。这对您来说可能是一个小问题,或者如果您有现有的工具/脚本/等对数据字典运行查询以生成 DDL 或确定需要分配多少内存或其他一些您最终会遇到的情况得到时髦的结果。

  • 但是,所有数据使用单个字符集的优势远远超过了这些缺点
  • 搬运 NVARCHAR2列通常需要更改应用程序代码。由于您将同时拥有 VARCHAR2NVARCHAR2列,这些代码更改和配置设置可能非常重要,并且通常是一个主要的烦恼。不可避免地,您会发现在某些应用程序中错误地映射了特定列,并且会遇到难以追踪的数据损坏错误。数据库和应用程序之间的抽象层越多,这一点就越正确。
  • 如果今天有 1% 的列需要支持 Unicode,那么明天必然会有更多的列需要支持 Unicode。随着附加要求的增加,将列的数据类型从 VARCHAR2 更改为至 NVARCHAR2很痛苦——你需要添加一个新列,复制数据,删除旧列,重命名新列,并处理由此产生的行迁移。然后,您必须对所有现有应用程序进行更改,以便它们正确映射列。当企业决定需要再增加一个列来支持其他语言并且您的数据库和应用程序已经支持 Unicode 时,这种级别的努力和测试似乎相当过分。
  • SQL 语句必须以数据库字符集编码。如果您想使用来自 NVARCHAR2 的数据,这往往会产生问题。列作为 SQL 语句中的文字在应用程序中(例如,避免绑定(bind)变量窥视或更好地利用直方图)或作为生产支持的一部分,当您想要跟踪数据中的问题时。
  • Unicode character sets are the direction Oracle strongly encourages以及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/

    相关文章:

    mysql - mysql中的分组和顺序

    IN 子句中的 SQL 多列

    mysql - 一对多关系?

    sql-server - 分层组的数据库架构

    sql - 超过 4000 个字符在 Oracle 上给出字符串文字太长错误

    database - 我应该在哪里保存半临时数据库?

    php - 当我尝试在 yii 框架中执行查询时连接被重置

    sql-server - SQL 2008 数据类型 - 使用哪些?

    php - 验证 2 个值以确定 "Yes"或 "No"

    oracle - oracle DB中具有纬度和经度的两点之间的距离