MovableType で扱える各データカラムの最大サイズを求めようとして、ソースコードからしこしこと表を作ってみました。記事公開後、天野さんから、「バイト数じゃないんじゃない?」とのコメントを頂いたので、もうちょっと調べてみました。要は、データベースの文字コードの設定によって結果が違ってくるとのこと。
MySQL 5.1 リファレンスマニュアル :: 4 データベース管理 :: 4.2 mysqld — MySQL サーバ :: 4.2.3 システム変数 によると、MySQL では以下の7つのシステム変数によってキャラクタセットが定義されているらしい。
character_set_client
- クライアント送信の文字列のキャラクタ セット
character_set_connection
- キャラクタ セット情報がないリテラルの並びで、数値→文字と変換するときのキャラクタ セット。
character_set_database
- デフォルト データベースで使用するキャラクタ セット。デフォルト データベースが変化する度に、サーバがこの変数を変更する。デフォルト データベースが存在しない場合、この値は
character_set_server
と同一。character_set_filesystem
- ファイルシステムのキャラクタ セット。LOAD DATA INFILE や SELECT ... INTO OUTFILE などのステートメントや LOAD_FILE() 関数に対して、この変数でファイル名とリテラルの文字列を読み取る。
character_set_results
- クライアントへ返す文字列 (クエリ結果) のキャラクタ セット。
character_set_server
- サーバのデフォルトのキャラクタ セット。
character_set_system
- 識別子の書き出しにサーバが使用するキャラクタ セット。この値は常に utf8。
アプリケーション プログラムとデータベース サーバとのやり取りにおいて重要なのは、このうち、character_set_client
、character_set_connection
、character_set_results
の 3 つである。
character_set_client
- クライアント(アプリケーション プログラム)がデータベースに宛てて送信する文字列のキャラクタ セット。なので、アプリケーション プログラムが内部で利用している文字列と合わせてやる必要がある。シフトJIS で書かれたスクリプトなら、sjis に。
character_set_connection
- クライアントとのデータ送受信の接続において利用するキャラクタ セットで、このキャラクタセットでデータベースに格納されると考えてよい。もしも扱うデータに漢字キャラクタを含む場合には、少なくともこのキャラクタ セットを漢字の扱えるものに指定する必要がある。
character_set_results
- データベースがクライアント(アプリケーション プログラム)へ返す文字列のキャラクタ セット。
以上が、クライアントとデータベース間の文字コードの整合性のためのシステム変数。ただし、ここを正しく設定しても、データベース上では見た目、文字化けが発生したように見えることがある(phpMyAdmin など)。更に、character_set_database
を目的の文字コードに合わせる必要がある。
また、これらシステム変数の設定によってMovableType で扱える各データカラムの最大サイズが変わってくることが判った。VARCHAR(255)
のカラムに UTF-8 で 3 文字= 9 バイトのデータを書き込む場合を考える。character_set_database
が latin1 の場合、UTF-8 の文字列はバイトコードとして扱われるため、9バイト分のデータが書き込まれる。length(column)=9, bit_length(column)=72 となるため、UTF-8 の文字列は最大で 84 文字前後しか保存することができない。
一方、character_set_database
が utf8 の場合、UTF-8 の文字列は正しく UTF-8 として扱われ 3 文字としてカウントされる。すなわち、このカラムには最大で 255 文字の文字列を格納できる。length(column)=255, bit_length(column)=6120=(3*255*8) である。
データベースの文字コードが latin1 で動作していても、MovableType は文字化けなどを発生させずに一見、正しく動作しているように見える(入出力のところで文字コードの整合が取れてしまうため?)が、データベースのキャラクタセット設定によってはデータベース上のデータの格納のされ方に違いが生じる。これによって格納される文字列長さが本来想定されたものよりも小さくなる可能性がある。プログラムの本来の能力を発揮するため、また、これに起因する変なバグに悩まされないためにも、データベースのキャラクタセットは適切に設定されることが望ましい。