MySQLの文字コード

更新日 2010-03-13 (土) 10:28:02

文字コード取扱いの概要

文字コードの設定箇所

MySQL 4.1からはUTF8が利用できるようになり以下のように変更になった。
文字コードの設定箇所はクライアント側に設定する文字コードは1つだけだ。それに対して,サーバー側は4段階の文字コード設定がある。つまり,サーバー全体,対象データベース,対象テーブル,対象フィールドである。対象フィールドに文字コードが設定されていれば,その文字コードとクライアント文字コードでコード変換を行う。フィールドの文字コード設定 がなければ,テーブルの文字コード設定を使用する。そうでなければデータベースの文字コード設定を使用する。最終的には,サーバーの文字コードが設定される。

また、文字コードの変換処理は,必ず行われるわけではない。次の2つの条件では,文字コード変換は行われない。

  • クライアントとサーバーの文字コードが一致する場合
  • クライアントとサーバーのいずれかがbinaryの場合

注)クライアントとサーバーの文字コードが一致すると文字コード変換が発生しないので,文字化けが起こらないと思われている。しかし,それとは関係なく,エスケープ処理や解除処理が行われるので,文字化けが発生することがある。

laten1は1Byte文字なのでクライアントとサーバ共にlaten1だと見かけは文字化けしないが、文字化けするパターンが上記の理由により多々起こる。

ただし、クライアント側の文字コードがsjisやcp932などのマルチバイト文字の場合には,「0x5C」を削除しない。 「表」とう文字は,sjisで「0x955C」というコードである。それが,エスケープ解除処理によって「0x95」となる。エスケープ処理のチェックは「表」という漢字が文字化けしないことで確認できるかな?

エスケープ処理
「エスケープ処理」と「エスケープ解除処理」が行われ、「エスケープ処理」は 表の文字に関して「0x5C」を付加する。 このため「エスケープ解除処理」のとき上記のようなことがおきる。

表エスケープ対象文字
特殊な意味を持つコードコード
NULL0x00
LF0x0A
CR0x0D
Ctrl+Z0x1A
\0x5C
0x22
0x27

文字コードの設定概要

内容実施変更される側
クライアント側の文字コードを指定クライアントクライアントset names cp932
サーバー側の文字コードを指定サーバーサーバーdefault-charactes-set=cp932
データベース,テーブル,フィールドの文字コードを設定サーバーサーバーデータベーステーブルフィールドSQLステートメントで実施
接続時のクライアント側の文字コードを指定サーバークライアントinit_commect=’ set names cp932’
サーバー側と同じ文字コードに設定される。(文字コード変換の抑止)サーバークライアントskip-character-set-client-handshake

システムの設定文字コードの表示

クライアント、クライアントの接続時、データベース、サーバ等の文字コードの表示

mysql> show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | sjis                       |
| character_set_connection | sjis                       |
| character_set_database   | ujis                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | sjis                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

文字コードの設定方法

デフォルトの文字コードの指定はmy.cnfで指定を行う。以下にその設定を示す。

/etc/my.cnf

[mysql]の設定はmysqlコマンド(# mysql -u root -p test)で実行される設定
[client]はすべてのクライアントプログラム(mysqldは除く)によって解読される。これによって全てのクライアントに当てはまるオプションを指定する

mysqlコマンドは[client]より[mysql]のほうが優先順位が高い?

PHPやPerlはmy.cnfを読まないのでこれとはまた違う話になるので注意

[client]
default-character-set = utf8

を指定すると、以下の設定が変更される

character_set_client     | utf8 
character_set_connection | utf8 <==クライアント接続時にクライアント側の文字コードの初期値を指定
[mysqld]
default-character-set=utf8

を指定すると、以下の設定が変更される

character_set_database   | utf8 <==ただし、すでにDBがあるときは変更不可
character_set_server     | utf8

上記の文字コードの設定のとき上のmy.cnfに変更し再起動すると以下のようになる。
ただし、データベース作成以前実行。

mysql> show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

フィールドの設定文字コードの表示

mysql> show full columns from t_test;
+-------+-------------+------------------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type        | Collation        | Null | Key | Default | Extra | Privileges                      | Comment |
+-------+-------------+------------------+------+-----+---------+-------+---------------------------------+---------+
| ID    | varchar(8)  | ujis_japanese_ci | YES  |     | NULL    |       | select,insert,update,references |         |
| data2 | varchar(16) | ujis_japanese_ci | YES  |     | NULL    |       | select,insert,update,references |         |
| data3 | varchar(64) | ujis_japanese_ci | YES  |     | NULL    |       | select,insert,update,references |         |
+-------+-------------+------------------+------+-----+---------+-------+---------------------------------+---------+
3 rows in set (0.00 sec)

データベース作成時に文字コード設定

mysql> CREATE DATABASE hoge CHARACTER SET UTF8;

テーブル作成時に文字コード設定

テーブル作成時に全体の文字コード設定

mysql> create table t_test2(
    -> ID    int8,
    -> data  varchar(64),
    -> name  varchar(64)
    -> ) character set sjis;
Query OK, 0 rows affected (0.02 sec)

テーブル作成時のフィールドごとの文字コード設定

t_test.create
create table t_test (
  ID           int8,
  data2          int8,
  data3          varchar(64) character set utf8   <--このフィールドをUTF-8に指定
);

それぞれに指定がない時は以下の順で文字コードが指定ができる指定がない場合は順に右側に従う

(優先:高)フィールド > テーブル > データベース > サーバ(優先:低)

各パラメータの意味

character_set_system

 "indentifiers" (テーブル名,フィールド名) を格納するのに使用
 utf8で 固定。

character_set_server

サーバの文字セットです。上のcharacter_set_databaseで説明したように、この文字
セットは、データベース作成時の暗黙の文字セットとして使用されます。この変数は
サーバ起動時のオプションとして初期設定できます。(my.cnf)の[mysqld]セクションで、

default-character-set=utf8

character_set_database

 CREATE DATABASE で文字コードが指定されなかった場合、database の文字コー
 ドはこれになる。
 character_set_connection の値に影響する。(後述)

character_set_client

 クライアントから渡された SQL 文はこの文字コードであると解釈される。

character_set_connection

 キャラクタセットイントロデューサ (例えば『_ujis'ほげ'』)が省略された
 SQL 文中の文字列リテラルはこの文字コードであると解釈される。つまり
 サーバーはクライアントからのSQL文をcharacter_set_clientからcharacter_set_connectionに変換

character_set_results

 サーバーがクライアントに返す結果をこの文字コードに変換する。
 この変数を NULL にセットすると、結果に対する文字コード変換をしないよ
 うにできる。

MYSQLクライアントの文字コードの設定

データベース上の文字コードの設定とデータの文字コードが一致していれば以下のように表示ができる。

SET (Variable_name)=(Value);

クライアントの文字コード変更はたとえば

mysql> SET NAMES UTF8;

以下の例はデータベース上の文字コードがUTF8でデータもUTF8の場合

Teartermの文字コードがUTF-8

mysql> SET NAMES UTF8;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t_test;
+------+-------+--------+
| ID   | data2 | data3  |
+------+-------+--------+
| 1    | 1001  | 西井   |
| 2    | 1002  | 山田   |
| 3    | 1003  | 田中   |
| 4    | 1004  | 福田   |
| 5    | 1005  | 表表   |
+------+-------+--------+
5 rows in set (0.00 sec)

Teartermの文字コードがSJIS

mysql> SET NAMES sjis;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t_test;
+------+-------+-------+
| ID   | data2 | data3 |
+------+-------+-------+
| 1    | 1001  | 西井      |
| 2    | 1002  | 山田    |
| 3    | 1003  | 田中     |
| 4    | 1004  | 福田     |
| 5    | 1005  | 表表    |
+------+-------+-------+
5 rows in set (0.00 sec)

EUCのときはujis

ODBC

ODBCもクライアント側なので、上記のルールの従ってODCBの設定で以下のようにすればAccessなどで文字化けせずに利用できる

Initial Statement: SET NAMES sjis

"注)"
もしデータ表示が#Deletedとなる場合はパスクエリーを使用する。
Mysqlの問題ではなくAccessとodbcの問題。

参考

http://itpro.nikkeibp.co.jp/article/COLUMN/20070614/274802/?P=1&ST=oss

ECCUBE

ECCUBE2で、以下の設定がないとインストール時PHPでテーブル作成時にUTF8にならずにmysqlコマンドでテーブルselectを行うと文字化けする(当然インストール前に設定する必要あり)

my.cnf

[mysqld]
init-connect=SET NAMES utf8  <==追加

クライアントが何であっても(PHPなど)接続時に “SET NAMES utf8″ を勝手に実行するとどこかのページに書いてあったが事実は不明。

my.cnfのテンプレート

/usr/share/mysqlにいくつかのテンプレートがあるが、my-medium.cnfではODBCでうまく読めたがmy-large.cnfでは文字化けをした。差分は

my-medium.cnf

net_buffer_length = 8K

があり

my-large.cnf

thread_cache_size = 8
query_cache_size= 16M
# Try number of CPU's*2 for thread_concurrency
thread_concurrency = 8

がある

一度my-medium.cnfにして文字化け修正するとmy-large.cnfに戻しても文字化けしなくなった。不思議????

.htaccessでphp.iniの値を変更

php_value default_charset Shift_JIS
php_value mbstring.language Japanese
php_flag mbstring.encoding_translation On
php_value mbstring.http_input auto
php_value mbstring.http_output SJIS
php_value mbstring.internal_encoding EUC-JP

などとすると.htaccessのあるディレクトリではphp.iniより優先される。


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-03-13 (土) 10:28:02 (3145d)