[前][次][番号順一覧][スレッド一覧]

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>]