2009年04月02日

国際化キャラクタ・セットの選択(2)

今回は国際化キャラクタセットの設定値として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点目の恩恵を受けることができますので、全く選択の余地がないわけではありません。

2009年03月16日

国際化キャラクタ・セットの選択(1)

大分間隔が空いてしまいました。

今回は国際化キャラクタ・セットの選択についてです。
国際化キャラクタ・セットについてはOracle9i物理設計では簡単にしか書いていませんし、割とベテランのOracleエンジニアの方でも国際化キャラクタ・セットについてはよくご存じない方がいらっしゃる分野だったりします。なので、今回はまず国際化キャラクタ・セットとは何ぞや、というところを中心にお話したいと思います。

国際化キャラクタ・セットもデータベースのキャラクタ・セットのひとつです。NCHAR型・NVARCHAR2型・NCLOB型といった、頭に「N」がつく文字列型のデータをデータベースに格納する際の文字コードの指定になります。これらのデータ型とCHAR型やVARCHAR2型、CLOB型といった普通の文字列型との違いは文字コード変換の方法にあります。普通の文字列型のデータは、DBのキャラクタ・セットとクライアント側の環境変数(Windowsの場合はレジストリ変数でも可)NLS_LANGに設定したキャラクタ・セットが異なる場合、文字コードの変換が発生します。一方の国際化キャラクタ・セットでは、クライアントにデータが到達する際もデータベースに格納した文字コードのままでコード変換が発生しません。この際NLS_LANGはエラーメッセージや日付のデフォルト書式などのみに影響します。

国際化キャラクタ・セットは「国際化」と名のつく通り、多言語環境を意識しています。そのため、指定できるキャラクタセットにはJA16SJISTILDEやJA16EUCといった特定の国の文字中心のものが存在しません。すべてUnicodeになります。デフォルトではAL16UTF16、他にはUTF8が選べるのみです。基本的にはデフォルトのAL16UTF16を指定するようにしましょう。AL16UTF16を指定するメリットや、AL16UTF16とUTF8の指定の使い分けなどについては次回に解説したいと思います。

2009年01月28日

データベースのキャラクタ・セットの選択(2)

前回はキャラクタ・セットは基本的にAL32UTF8を選ぶべしという話をしました。今回は、前回予告した通り、AL32UTF8もいいことばかりじゃないよということについて書きたいと思います。

まず、なんだかんだで、シフトJISの半角1バイト、全角2バイトという設計は人に非常にわかりやすいということですね。ご存知の方が大半だとは思いますが、UTF-8の場合、全角は3バイトになります。半角文字は基本1バイトですが、半角カナは3バイトです。UTF-8の場合、あるデータの文字数から消費バイト数を考える時の計算が面倒です。

また、DB容量の増加という問題があります。純粋な会計システムとか生産管理システムなどですと、漢字のようなデータが占める割合が低いケースも多いかと思います。一方でBlogサイトみたいな文章中心のデータを扱うシステムですと、文字コードをUTF-8にすることによるデータベースサイズの増加が馬鹿になりません。更に言えば、最近のUnicodeはサロゲートペアといって、より多くの文字を表現できるように、よりたくさんのバイト数を使って1文字を定義することもできるようになっています。文字種によっては1文字でより多くのバイト数を使います。たとえばWindows VISTAで使えるようになったJIS2004特有の文字(例えば森鷗外の「鷗」などです。AL32UTF8採用の利点として、JIS2004対応という点もありますね。)は、UTF-8では1文字4バイトになります。

最後に、文字サイズに絡むのですが、もしテーブル名や列名などを日本語で定義したい場合、つけられる文字数の上限がシフトJISよりも下がってしまいます。Oracle Databaseの基本的なオブジェクト名の長さの上限は30バイトですので、シフトJISだと基本的に15文字まで使えますが、UTF-8ですと基本10文字までになってしまいます。もしJIS2004特有の文字を使えば、更に上限が減ります。

話は逸れますが個人的には上限を100バイトくらいにしてもらえると嬉しいのですね・・・。更に話は逸れますがオブジェクト名に日本語を使用する是非についてもいずれ思うところを書きたいと思います。

個人的には、これらのデメリットよりも、使うことによるメリットの方が大きいと考えています。もちろん個別案件では異なる選択をした方がよいケースもあるでしょうが、ここで挙げた様なデメリットがノックアウト・ファクターにならないのであれば、AL32UTF8を選択した方がいいと考えます。

次回は国際化キャラクタ・セットの選択について書きたいと思います。

2009年01月13日

データベースのキャラクタ・セットの選択(1)

一応旧コンテンツの順番で解説して行こうと思いますが、特にアップデートのない事項は飛ばして行きたいと思います。で、最初のブロックサイズの話をいきなり飛ばして、データベースのキャラクタ・セット(データベースの作成時に指定する、データベースの中の文字列の文字コード)の選択について書きたいと思います。

Oracle Databaseで利用できるキャラクタ・セットについては10gでも11gでも9iの頃と特に変わりはありません。ただ、利用可能なUnicodeのバージョンが上がっています。これもUnicodeのバージョン自体が下位互換があるので、AL32UTF8やAL16UTF16などを使用している限りはバージョンアップしてもデータベースのレベルでは文字化けなどの問題の心配はありません。

新規のシステムにおいては、特に要件がなければ、キャラクタ・セットはAL32UTF8を使用することをお勧めいたします。理由は、一言で言うならば国際化への対応、になります。日本国内での使用しか想定してないよ、という向きもあるかもしれませんが、以下のような事情もご考慮ください。

・Javaにしても.Netにしても内部の基本文字コードはUnicodeです。その他Unicodeが前提なツール、開発環境などが増えています。データベースも含め徹頭徹尾Unicode利用する環境にすれば「~」の文字化けの問題などの発生も抑えられます。
・昨今は国内向けシステムであっても中国系の方などでUnicodeでないと扱えない字の方のお名前がデータとして登録されるケースが増えてきていると思います。カタカナで対応するという手もないわけではないですけど。
・オフショア開発を考慮した場合、アプリ環境のみならずデータベースも含めて利用文字コードをUnicodeに統一した方が文字コードに絡む問題が起こりにくいです。

とはいえいい話ばかりでもないので、そのあたりについては次回に書きたいと思います。

2009年01月07日

よろしくお願いします

はじめまして、もしくはこんにちは。Oracle9i物理設計の筆者、中家裕之(なかいえ ひろゆき)です。

リンク先の記事はもう6年前になるのですね(最終更新日が2004/1/21となっていますが、1年かけて連載してます)。読み返してみて我ながら時の流れの速さに驚いている次第です。この記事、おかげさまでいまだにそこそこのアクセスがあるようです。一方でもう6年も経っており、データベースのバージョンも2個上がってしまっているのもあって、タイトルからしていかにも古臭いですよね。といいつつも書いていることの大半はOracle Database10gや11gでも通用するのですが。

当然ですが、より新しいバージョンのOracle Databaseでは新機能などにより設計がもっと楽になったり性能が上がったりする部分なども出てきております。そういったところでは、上位バージョンにおいてはあの記事通りでないやり方の方がよりいい部分もあります。また、長年色々な方から新しいバージョンベースで記事を書いてほしいとのリクエストをたくさんいただいております。前回よりバージョンがひとつ空いた、のんびりした再開ではありますが、ブログ形式でOracle Database 11gベースのデータベース物理設計を中心に色々書いていきたいと思います。

DB物理設計以外にも、現在自分がテーマとしているセキュリティやDB論理設計、PL/SQLの話などもできればなと思っています。というかだんだんそちらが中心になっていきそうな予感が今からしてますが、ともあれ頑張って更新していきたいと思いますのでご期待ください。