2013年3月15日金曜日

MySQLの文字コードセット「utf8」と「utf8mb4」

 MySQLの文字コードセット「utf8」は3バイトまでのサポートで4バイトをサポートするのはMySQLバージョン5.5以降からサポートしている文字コードセット「utf8mb4」であるとのことを今更ながら知りました.

MySQL 5.0 Reference Manual > 10.1.10. Unicode Support
http://dev.mysql.com/doc/refman/5.0/en/charset-unicode.html
MySQL 5.5 Reference Manual > 10.1.10. Unicode Support
http://dev.mysql.com/doc/refman/5.5/en/charset-unicode.html

簡単なコード(PHP)で動作検証してみました.

$conn=mysql_connect('192.168.0.5:3306','admin','password');

if($conn){
    if(mysql_select_db('test2',$conn)){
        $res=mysql_query('SET NAMES utf8',$conn);        
        if(!$res){
            print(mysql_error()."\n");
        }
        $res = mysql_query("DELETE FROM test");
        if(!$res){
            print(mysql_error()."\n");
        }
        $str="𪀚";
        printf("%s %d bytes\n",$str,strlen($str));
        var_dump(bin2hex($str));
        $res = mysql_query("INSERT INTO test (title) values ('".$str."') ",$conn);
        if(!$res){
            print(mysql_error()."\n");
        }
        $str2="田";
        printf("%s %d bytes\n",$str2,strlen($str2));
        var_dump(bin2hex($str2));
        $res = mysql_query("INSERT INTO test (title) values ('".$str2."') ",$conn);
        if(!$res){
            print(mysql_error()."\n");
        }
        $res=mysql_query('SELECT * FROM test',$conn);
        if($res){
            while($row = mysql_fetch_assoc($res)){
                printf("%s\n",$row['title']);
            }
            mysql_free_result($res);
        }else{
            print(mysql_error()."\n");
        }
    }
    mysql_close($conn);
}

コードでは2つの漢字「𪀚」(鳥+戎)と「田」をデータベースに登録し,検索表示しています.

MySQL 5.0.87の場合,
4バイトの文字があってもエラーは表示されません.
無視されるだけです.

$ php test.php
𪀚 4 bytes
string(8) "f0aa809a"
田 3 bytes
string(6) "e794b0"

また,当然「utf8mb4」はサポートしていませんので,使用しようとするとエラーとなります.

$ php mysql.php
Unknown character set: 'utf8mb4'
𪀚 4 bytes
string(8) "f0aa809a"
田 3 bytes
string(6) "e794b0"

MySQL 5.6.10の場合は4バイトの文字「𪀚」をutf8で登録しようとするとエラーとなります.
$ php test.php
𪀚 4 bytes
string(8) "f0aa809a"
Incorrect string value: '\xF0\xAA\x80\x9A' for column 'title' at row 1
田 3 bytes
string(6) "e794b0"
「utf8mb4」を使うと4バイトの文字をちゃんと登録することができます.
$ php test.php
𪀚 4 bytes
string(8) "f0aa809a"
田 3 bytes
string(6) "e794b0"
𪀚
この投稿では文字化けしてるけど.

4バイト文字を「utf8mb4」で登録できる事はわかったけど,5.0から5.5に移行するにはSQLの変更も必要そう.インデックスサイズも変更となるし.

取りあえず,そういう問題があることだけは把握しておこう.



0 件のコメント:

コメントを投稿