utf-8 で 3byte 使ってる文字があるの知らなかったので豆腐の角に頭ぶつけてきます

タイトルで言い切った(一度使ってみたかった)。勉強ついでに Unicode の表をみてたら「ぁ」とかどういう値になるんだろうなぁと思って Java のコードを書いてみて気がついた。

public static void main(String args[]) throws Exception {
    print("ぁ" , "SJIS");
    print("ぁ" , "Windows-31J");
    print("ぁ" , "UTF-8");
    print("ぁ" , null);
}
private static void print(String msg , String encoding) throws Exception {
    byte[] bytes = encoding == null ? msg.getBytes() : msg.getBytes(encoding);
    for(int i = 0 ; i < bytes.length ; i++) {
        System.out.print(bytes[i] + " ");
    }
    System.out.println("\n------------------------------------");
}

特にひねりはなくて、各文字コードの byte 列を取得して出力してるだけ。これの結果がこれ

-126 -97
------------------------------------
-126 -97
------------------------------------
-29 -127 -127
------------------------------------
-126 -97
------------------------------------

で、気づいた・・・ん?あれ?UTF-8 が 3 byte あるΣ(ΦДΦ;)

デメリット
漢字(仮名含む)の表現に3バイトを要する。そのため日本語の文章はShift_JISEUC-JPなどと比較して1.5倍のサイズとなる。

UTF-8

だとな。今の今まで全部 2 バイトだと思ってた \(^o^)/オワタ
となると UTF-8 な環境の場合、クライアントで最大 2 byteでチェックして DB に格納したら\(^o^)/オワタ ってこともあるんじゃないのか?と思ってググったら IBM のページが出てきた。

「文字列の最大長を"入力が想定される文字数"*3で設定しておけば、運用上安全です。 」

DB2 UDB: UTF-8の場合のDBのカラム桁数定義について

特にひねりなし \(^o^)/
ありがたいことにこんなお馬鹿な発言に Wassr で返信を幾つかもらった。

MySQLなどは、str as varchar(2) とか指定すると、6byte確保される。マルチバイトが可変長というのは、DBにとっても発想にない事だったのか、対応はDBによってまちまち。

し(゜▽し゜)ゃ

ちなみに Ruby 1.8.7 でもやってみた。utf-8 でファイルを保存して実行する

#!ruby -Ku
puts "".length #=> 3

当たり前な結果なんだけど・・・日本語でOK(Windowsな意味で)に慣れすぎた orz
自分で気づいて良かった。勉強大事。MySQL でいろいろ試してみたかったけど時間がないので今日はここまで。