mysql:9586
From: "HIROSE, Masaaki" <"HIROSE, Masaaki" <hirose31@xxxxxxxxxx>>
Date: Thu, 10 Jun 2004 02:48:25 +0900
Subject: [mysql 09586] Re: MySQL 4.1.2 の日本語の扱い
ひろせといいます on "[mysql 09573] Re: MySQL 4.1.2 の日本語の扱い" <20040608.115153.52192899.fuji@xxxxxxxxxx> at Tue, 08 Jun 2004 11:51:53 +0900 (JST) Hirofumi Fujiwara <fuji@xxxxxxxxxx> wrote: > > > PostgreSQLではset CLIENT_ENCODING=sjisのようにクライアントの > > > 文字コードセットを選択できるので同じような実装にしても良いので > > > はないかと。 > > > > MySQLでもset names sjis(あるいはset character set sjis)とかで指定で > > きますよ。いちおう。 > > http://dev.mysql.com/doc/mysql/en/Dynamic_System_Variables.html > Dynamic System Variables として、character_set_client があります。 > この変数は GLOBAL or SESSION で変更できるので、一応困らないのでは。 (snip) いろいろ試してみました。間違っていたらつっこみお願いします。 少なくとも mysql コマンドに限っていえば、個人的には、 o my.cnf の [mysqld] に default-character-set = utf8 と書いておく。 utf8 が一番大きな文字集合なので。 o mysql コマンドはもっぱら euc-jp な環境で使うので、 my.cnf の [mysql] に default-character-set = ujis と書いておく。 o CREATE DATABASE するときは sjis なり ujis なり文字コードを明示的に 指定する。 o ひとつのデータベースに複数の文字コードのテーブルを混在させない。 o ひとつのテーブルに複数の文字コードのカラムを混在させない。 のルールを守ればトラブらないんじゃないかと思います。 // # MySQL 4.1.2-alpha-Max-log でのお話。 ■ 文字コードに関するシステム変数 ● 種類 以下の 6 つ。 mysql> show variables like 'character\_set\_%'; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | character_set_client | ujis | | character_set_connection | ujis | | character_set_database | utf8 | | character_set_results | ujis | | character_set_server | utf8 | | character_set_system | utf8 | +--------------------------+-------+ ● システム変数の用途 character_set_system "indentifiers" (テーブル名とかカラム名?) を格納するのに使われる。 utf8で 固定。 character_set_server character_set_database のデフォルト値に影響する。 character_set_database CREATE DATABASE で文字コードが指定されなかった場合、database の文字コー ドはこれになる。 character_set_connection の値に影響する。(後述) character_set_client クライアントから渡された SQL 文はこの文字コードであると解釈される。 character_set_connection キャラクタセットイントロデューサ (例えば『_ujis'ほげ'』)が省略された SQL 文中の文字列リテラルはこの文字コードであると解釈される。 character_set_results サーバーがクライアントに返す結果をこの文字コードに変換する。 この変数を NULL にセットすると、結果に対する文字コード変換をしないよ うにできる。 # 以下、長いので "character_set_" は "cs_" に省略する。 ● システム変数の制御方法 個別に SET character_set_client charset_name などとする以外の制御方法。 SET CHARACTER SET charset_name → cs_client charset_name cs_connection (cs_databaseの値) cs_results charset_name SET CHARACTER SET charset_name を実行すると、cs_client と cs_connection の値が charset_name になり、cs_results の値が cs_database の値と同じになる。 SET NAMES 'charset_name' → cs_client charset_name cs_connection charset_name cs_results charset_name mysql --defalt-character-set charset_name → cs_client charset_name cs_connection charset_name cs_results charset_name mysqld --defalt-character-set charset_name → cs_database charset_name cs_server charset_name ■ システム変数の影響 ● mysql コマンドで INSERT する場合 mysql コマンドで INSERT する場合に限って、これらのシステム変数がどのよ うに影響するか観察する。 # 以下、かなり自信ないです。 サーバーは、クライアントから送られた SQL 文中の文字列リテラルの文字コー ドを cs_client から cs_connection に変換する。ただし、キャラクタセット イントロデューサが指定されている文字列リテラルにはこの変換処理は適用さ れない。 参照: <URL:http://dev.mysql.com/doc/mysql/en/Charset-connection.html> その後、格納する文字コード*1 に変換してストレージに格納する。 *1 優先度が高い順に以下のいずれか。 1. カラムの文字コード指定。 2. テーブルの文字コード指定。 3. データベースの文字コード指定。 例: # ujisの『あ』をlatin1に変換しようとするが、できないので『?』になる。 cat <<EOF | mysql -u hirose31 --default-character-set=ujis test set character_set_connection = latin1; show variables like 'character%'; insert into t_ujis values ('Aあ'); EOF # イントロデューサをつければ OK cat <<EOF | mysql -u hirose31 --default-character-set=ujis test set character_set_connection = latin1; show variables like 'character%'; insert into t_ujis values (_ujis'Bあ'); EOF # cs_client(=ujis) とイントロデューサ(=_sjis)が異なっていても大丈夫。 # → イントロデューサが指定されている場合は cs_client から # cs_connection への変換は行われない。 cat <<EOF | nkf -Es | mysql -u hirose31 --default-character-set=ujis test set character_set_connection = latin1; show variables like 'character%'; insert into t_ujis values (_sjis'Cあ'); EOF cat <<EOF | mysql -u hirose31 --default-character-set=ujis test select * from t_ujis; EOF s A? Bあ Cあ ● cs_connection の値に注意する SET CHARACTER SET charset_name すると、cs_connection は charset_name ではなく cs_database の値になる。また、cs_database の値はカレントデー タベースの文字コード (DATADIR/DBNAME/db.optがあればそれに、なければ cs_serverの値) になる。 なので、例えば mysql で接続して latin1 なデータベースに use dbname で移 動 (この時点で cs_database が latin1 になる) した後に SET CHARACTER SET ujis を実行すると、 cs_client は ujis になるが cs_connection が (cs_databaseと同じ) latin1 になってしまうので、日本語の INSERT などが 期待通りにならない。 回避するには * use dbname の前でも後でもいいので SET NAMES 'ujis' する。 * mysql --default-character-set=ujis で接続して、SET CHARACTER SET も SET NAMES も実行しない。 などの方法がある。 // -- ひろせ http://www.irori.org/
9530 2004-06-03 23:28 [とみたまさひろ <tomm] MySQL 4.1.2 の日本語の扱い 9531 2004-06-04 01:51 ┗[とみたまさひろ <tomm] 9533 2004-06-04 08:26 ┣[SUGAWARA Hajime <sug] 9547 2004-06-07 19:25 ┗[<takeshi@xxxxxxxxxx>] 9550 2004-06-07 21:09 ┣["Ryuichiro Munechika] 9556 2004-06-07 22:02 ┃┗[SUGAWARA Hajime <sug] 9573 2004-06-08 11:51 ┃ ┗[Hirofumi Fujiwara <f] -> 9586 2004-06-10 02:48 ┃ ┗["HIROSE, Masaaki" <h] 9628 2004-06-13 21:50 ┃ ┗[Hirofumi Fujiwara <f] 9578 2004-06-09 08:05 ┣[とみたまさひろ <tomm] 9580 2004-06-09 09:39 ┃┗[<takeshi@xxxxxxxxxx>] 9592 2004-06-11 05:04 ┗[<shuichi@xxxxxxxxxx>] 9596 2004-06-11 11:00 ┣[<shuichi@xxxxxxxxxx>] 9598 2004-06-12 00:16 ┗[<takeshi@xxxxxxxxxx>] 9611 2004-06-12 21:55 ┗[とみたまさひろ <tomm] 9687 2004-06-18 09:40 ┗[<takeshi@xxxxxxxxxx>] 9699 2004-06-23 09:41 ┣[<takeshi@xxxxxxxxxx>] 9728 2004-07-01 11:18 ┗[<takeshi@xxxxxxxxxx>] 9756 2004-07-02 21:14 ┗[<takeshi@xxxxxxxxxx>] 9808 2004-07-10 16:55 ┗[<takeshi@xxxxxxxxxx>] 9839 2004-07-13 14:26 ┗[Shuichi Tamagawa <sh] 9842 2004-07-13 15:12 ┣[Hirofumi Fujiwara <f] 9848 2004-07-14 09:35 ┃┗[<shuichi@xxxxxxxxxx>] 9850 2004-07-14 09:56 ┃ ┗[<takeshi@xxxxxxxxxx>] 9852 2004-07-14 12:25 ┃ ┗[Hirofumi Fujiwara <f] 9854 2004-07-14 13:39 ┃ ┣[<takeshi@xxxxxxxxxx>] 9858 2004-07-14 15:31 ┃ ┃┗[Hirofumi Fujiwara <f] 9860 2004-07-14 16:35 ┃ ┃ ┣[<takeshi@xxxxxxxxxx>] 9867 2004-07-16 02:16 ┃ ┃ ┗[Shuichi Tamagawa <sh] 9863 2004-07-15 11:34 ┃ ┗[<shuichi@xxxxxxxxxx>] 9847 2004-07-14 08:52 ┗[<shuichi@xxxxxxxxxx>] 9849 2004-07-14 09:39 ┗[<takeshi@xxxxxxxxxx>]