Jul 4, 2006

MySQLのキャラクターセット

ドキュメントを読まない私が、いまさらMySQLのキャラクターセットで結構面倒な作業をさせられたのでその記録。

  • もともとMySQL 4.0.xを使っていた。
  • 「skip-character-set-client-handshake」オプションが導入された4.1.15が出たタイミングで、4.1.15に移行した。
  • このとき、「--with-charset=latin1」でコンパイルされ、かつmy.cnfなどでdefault-character-setを特に指定していないMySQL 4.1.15で、4.0からアップグレードした。したがって各データベースのテーブルには、「DEFAULT CHARSET=latin1」が付与された。
  • 「skip-character-set-client-handshake」付きでmysqldを起動していたので付与されるDEFAULT CHARSETがなんだろう構わないと思って、特に気に留めていなかった。強いて言えばphpMyAdminで文字化けするくらいの問題しかなかった。

と、ここまでが現状。

今回、MySQL 5.0.22にアップグレードした。「skip-character-set-client-handshake」付きならまったくそのままで構わないのだが、そろそろ4.1以降で導入されたキャラクターセット機能を使ってみようかと思ったわけだ。

ひとまず、DBの中身は全部utf-8なので特に考えることはない。my.cnfに以下のように追加してmysqldを再起動する。

[mysqld]
default-character-set = utf8
[mysql]
default-character-set = utf8
[mysqldump]
default-character-set = utf8

次に、どうやって各テーブルに付いたDEFAULT CHARSETをlatin1からutf8に変更するのかなと思った。

普通に考えて、ALTER TABLEを使って、

ALTER TABLE hageTable CHARACTER SET utf8;

とやると修正できるような気がした。しかし、実際やってみるとhageTableのDEFAULT CHARSETは間違いなく変更されるのだが、今度はフィールドに元のcharsetがセットされてしまう場合があるようでどうもおかしい(すでにINSERT済みのレコードがあるときにそうなるのかな?)。TABLEの数だけALTER TABLEを実行しなくてはならないのも腹立たしい。

次に、そうだ、mysql40互換形式でダンプしてからリストアすればいいじゃんか、と思った(思っちゃ駄目!)。

$ mysqldump -uUser -pPassword --compatible=mysql40 hageDb > hage.sql
  (drop & create)
$ mysql -uUser -pPassword hageDb < hage.sql

で、これをやると何が起こるかというと、フィールドのauto_increment修飾子が落ちてしまって致命的におかしなことになる。

仕方がないのでもう少しだけ深追いしようと思って、面倒だけど普通にダンプしてsedで書き換えてからリストアしてみることにした。

$ mysqldump -uUser -pPassword --compact --default-character-set=binary hageDb > hage.sql
$ sed 's/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/g' hage.sql > hagehoge.sql
  (フィールドにcharsetが付いている場合にはその分も変換すること)
  (drop & create)
$ mysql -uUser -pPassword hageDb < hagehoge.sql

ひとまずちゃんと動いているようだ。しかし、なんだ、やり方が美しくない。とても不満が残る。

もっとうまいやり方があったら教えてください。

About Me

My Photo

つくばで働く研究者

Total Pageviews

Amazon

Copyright 2012 Ogawa::Buzz | Powered by Blogger
Design by Web2feel | Blogger Template by NewBloggerThemes.com