2019.4.17
2020.1.7

「VARCHAR2」と「NVARCHAR2」の違い

Oracleでテーブルのカラムに可変長の文字列型を定義しようとした時、「VARCHAR2」と「NVARCHAR2」の違いがよく分からなかったので、その時のメモになります。

調べる前は単純にバイト数と文字数の違いと思っていましたが、やはり違いました。

目次

  • VARCHAR2とNVARCHAR2のサイズの指定の仕方
  • VARCHAR2で文字数を指定した場合とNVARCHAR2の違い
  • 参考リンク

VARCHAR2とNVARCHAR2のサイズの指定の仕方

まず、VARCHAR2についてですが、テーブル作成時にカラムの定義を以下のようにVARCHAR2(20)とすると、格納可能なバイト数が20バイトで作成されます。(デフォルトがBYTE)


CREATE TABLE TABLE1
(
    COLUMN1 VARCHAR2(20) 
);

これを明示的にバイトで指定する場合は、VARCHAR2(20 BYTE)とします。

そして、初めてOracleを扱う場合に見落としがちなのが、VARCHAR2のサイズには文字数を指定することも可能な点で、文字数で指定する場合、以下のようにVARCHAR2(20 CHAR)とすることができます。


CREATE TABLE TABLE2
(
    COLUMN1 VARCHAR2(20 CHAR) 
);

一方のNARCHAR2は、サイズに指定した数値がそのまま格納可能な文字数となります。


CREATE TABLE TABLE3
(
    COLUMN1 NVARCHAR2(20) 
);

以下に、VARCHAR2で文字数を指定してカラムを作成した場合と、NVARCHAR2で作成した場合の違いについて記します。

VARCHAR2で文字数を指定した場合とNVARCHAR2の違い

VARCHAR2のサイズはバイト数以外に文字数でも指定することができることが分かりましたが、では、VARCAHR2(20 CHAR)NVARCAHR2(20)は書き方が違うだけで同じことなのかというと、どうやら違うみたいです。

では、なにが違うかというと、VARCAHR2とNVARCHAR2で格納できる文字コードが違うようで、NVARCHAR2に関してはUnicodeのみサポートしているようです。

データベースのキャラクタ・セットについてはインストール時に設定できるようですが、Oracleをデフォルトのままインストールした場合、キャラクタ・セットは以下のようになります。

  • NLS_CHARACTERSET = AL32UTF8
  • NLS_NCHAR_CHARACTERSET = AL16UTF16

上記の場合、VARCHAR2はUTF-8、NVARCHAR2はUTF-16となります。

自分の環境がどうなっているのかは、以下のSQLを実行して確認できます。


SELECT * FROM NLS_DATABASE_PARAMETERS;

これを見て、まあ、文字コードは違うけど、そこまで気にしなくていいのかと思いましたが、それは大きな間違いでした。

どうやらNVARCHAR2(UTF-16)で定義したカラムに、サロゲートペアを含む文字を格納してしまうと、LENGTH()で文字数のカウントを取得した際に、サロゲートペアの文字を2文字分としてカウントしてしまうようです。(詳しくはこちらを参照)

普通であれば、サロゲートペアの文字についても1文字でカウントしてほしいですよね。

そのため、通常、文字数でカラムのサイズを指定する場合は、VARCHAR2を利用するようです。

参考リンク

Oracle】関連記事