6

テーブルの一部の列はUnicode文字をサポートする必要があります(すべての列の1%としましょう)。

私には次の2つの選択肢があると思います。

  1. Unicode列をNVARCHAR2として実装します; また
  2. データベース全体の文字セットをUnicodeをサポートする文字セットに変更します(この方法でVARCHAR2を使用できます)。

私は2番目のオプションに傾倒しています(既存のVARCHAR2スクリプトを変更する必要がないようにするため)。

私の質問は、最初のオプションと比較した場合、この2番目のオプションの欠点と利点は何ですか?パフォーマンスが低下していますか?

4

1 に答える 1

8

私はデータベースの文字セットを変更することに強く傾倒します。

そうすることには潜在的な欠点があります

  • 他の列の7ビットASCII文字セットにないデータを格納する場合は、データを格納するために必要なスペースの量が増えます。既存の文字セットが英語と他のいくつかの言語を格納できる8ビット文字セットの1つであるとすると、データ内の英語以外の文字は通常、文字ごとに2バイト以上のストレージを必要とします。たとえば、文字「h」を格納している場合、これは7ビットASCII文字セットの一部である英語文字であるため、シングルバイト文字セットまたはUnicode文字セットのいずれかに1バイトが必要になります。一方、文字「À」を格納する場合、それは英語ではなく、7ビットASCII文字セットの一部ではないため、Unicode文字セットで2バイトのストレージが必要になります。既存のシングルバイト文字セットの1バイト。他の文字には3バイトのストレージが必要です。
  • を宣言するときは、文字とバイトのセマンティクスに注意する必要がありますVARCHAR2。デフォルトでは、VARCHAR2(50)50バイトのストレージが割り当てられます。これにより、AL32UTF8文字セットを使用している場合は、シングルバイト文字を使用している場合のように単純な1:1マッピングではなく、16〜50文字を格納できます。セットする。そのためには、列のサイズを大きくして(つまり、3倍にして)適切な文字数を格納するか、列を宣言するときに文字長のセマンティクスを指定するか(つまり、 )を前にVARCHAR2(50 CHAR)設定する必要があります。デフォルトを文字長セマンティクスに変更するためにオブジェクトを作成します。Oracle Globalizationフォーラムで、次のことが適切かどうかについての議論があります。NLS_LENGTH_SEMANTICSCHARNLS_LENGTH_SEMANTICSをインスタンスレベルで変更します-オラクルのトップグローバリゼーションの第一人者の1人であるSergiuszWolickiは、適切な状況下でそれを検討することを個人的にはるかに望んでいますが、これに強く反対しています。また、セッションレベルで設定することもできNLS_LENGTH_SEMANTICSます。これは、Sergiuszが反対しないものですが、問題になる可能性のあるスクリプトを実行するたびに設定する必要があります。
  • ほとんどのツールは、文字セマンティクスを使用して列を作成したデータディクショナリに対するクエリを特にうまく処理しません。文字単位の長さとバイト単位の長さを必要とする場所で、CHAR_LENGTHおよび列を適切に使用していません。DATA_LENGTHこれは、データディクショナリに対してクエリを実行してDDLを生成したり、割り当てる必要のあるメモリの量を決定したりする既存のツールやスクリプトなどがある場合、またはその他の状況で深刻な問題になる可能性があります。ファンキーな結果を得る。

ただし、これらの欠点は、すべてのデータに単一の文字セットを使用できるという利点よりも重要です。

  • NVARCHAR2通常、列を処理するには、アプリケーションコードを変更する必要があります。と列の両方VARCHAR2を使用するため、これらのコードの変更と構成設定は重要であり、多くの場合、大きな問題になります。NVARCHAR2必然的に、一部のアプリケーションで特定の列を誤ってマッピングしたことに気付くでしょう。また、追跡するのが面倒なデータ破損のバグに遭遇するでしょう。これは、データベースとアプリケーションの間にある抽象化レイヤーが多いほど当てはまります。
  • 今日、列の1%がUnicodeをサポートする必要がある場合、必然的に、明日はさらに多くの列がUnicodeをサポートする必要があります。追加の要件が追加されると、列のデータ型をからに変更するのVARCHAR2NVARCHAR2面倒です。新しい列を追加し、データをコピーして、古い列を削除し、新しい列の名前を変更して、結果として生じた行の移行。次に、既存のすべてのアプリケーションに変更を加えて、列を正しくマップする必要があります。もう1つの列が追加の言語をサポートする必要があるとビジネスが判断し、データベースとアプリケーションがすでにUnicodeをサポートしている場合、そのレベルの労力とテストはかなり過剰に見えるでしょう。
  • SQLステートメントは、データベースの文字セットでエンコードする必要があります。NVARCHAR2これは、アプリケーションでSQLステートメントのリテラルとして列のデータを使用する場合(たとえば、バインド変数のピークを回避するため、またはヒストグラムをより有効に活用するため)、または必要に応じて本番サポートの一部として使用する場合に問題を引き起こす傾向があります。データの問題を追跡します。
  • Unicode文字セットはOracleが強く推奨する方向NVARCHAR2であり、列の使用は強く推奨されていません。これはおそらくすぐに実際的な結果をもたらすことはありませんが、システムが何年も使用されていると想定される場合、将来的に結果が生じる可能性があります。

Sergiuszは、このスレッドでOracleのアドバイスを非常にうまくまとめています

オラクルのアドバイス:

  • 新しいデータベースの場合は、AL32UTF8文字セットを使用してデータベースを作成し、NCHARデータ型を忘れてください。
  • 既存のアプリケーションを多言語にする場合は、バックエンドデータベースをAL32UTF8に移行し、NCHARデータ型を忘れてください。
  • Unicodeに移行するにはコストがかかりすぎる、または不可能な大規模なレガシーアプリケーションシステムを提供する既存の非Unicodeデータベースの場合、多言語データをサポートする必要があり、別のデータベースがほとんど意味をなさないマイナーモジュールを追加する必要があります。この多言語データにはNVARCHAR2列を検討できます。
于 2012-10-09T13:52:03.767 に答える