今回は国際化キャラクタセットの設定値としてUTF8よりもAL16UTF16を推奨するメリットについて解説します。
まず一つ目として、日本語環境を考えた場合のDB容量の節約が挙げられます。UTF8では全角文字は基本3バイト消費しますが、UTF16では2バイト固定です。ただしUTF16ではASCII相当の文字も2バイトになるので、実際にどちらが特かどうかは格納したいデータの性質にも依存します。例えばBlogのようなコンテンツ系のデータを扱う場合などは全角データの割合が増えやすくなるのでUTF16を選択した方が有利です。一方で文字データの少ないシステムなどではUTF8が有利です。
二つ目として、文字コード変換の手間があります。前回のエントリで、国際化キャラクタセットの場合はクライアント/サーバー間で文字コードの変換が発生しないことを解説しました。つまり、クライアントで利用している言語やアクセス手法(ODBC, JDBC等)、NLS_LANGの設定にかかわらず、UTF16ないしUTF8のままデータが返されるということです。昨今の主流な言語であるJavaや.Netでは文字列データはUTF16で扱っていますので、国際化キャラクタセットをAL16UTF16で設定することにより、文字コード変換の回数を他のキャラクタセット設定と比べて減らすことができます。
この点を重要視すると、Javaや.Netを使う場合、テーブルの列データ型としてはCHAR/VARCHAR2/CLOBよりもNCHAR/NVARCHAR2/NCLOBを使った方がいいということになります。データベースは言語から独立して設計すべきという観点ではJavaだから、.Netだから、といった発想はあまりいいものではないですが、他の言語でもJavaや.Netより効果が薄いだけで変換回数自体は減らせますので、NCHAR/NVARCHAR2/NCLOBの利用は結果的には言語から独立した設計となりえます。とはいうもののNCHAR/NVARCHAR2/NCLOBはツールによっては扱えなかったりする場合がありますし、全角2バイト半角1バイトというわかりやすい設計のSJISなどに慣れてしまっている人が多い現状では、まだまだデータ型としては選択しづらいところかもしれません。
最後のメリットとして、UTF16はどの文字種も同じサイズなので、文字列操作の負荷が低くなります。例えばLENGTH関数やSUBSTR関数の負荷が下がります。言い換えると、これらの関数の処理速度が上がります。理由は、UTF8のような可変幅のキャラクタセットですと一文字の大きさを判断しながら処理を行いますが、UTF16の場合は大きさが一定なのでよりシンプルな内部処理になっているためです。
一方のUTF8も、C言語のような文字コードに依存しない言語、あるいは処理する文字コードを設定できるタイプの言語であれば2点目の恩恵を受けることができますので、全く選択の余地がないわけではありません。