Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 27.1Mb
PDF (A4) - 27.1Mb
EPUB - 7.5Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


MySQL 5.6 リファレンスマニュアル  /  MySQL 5.6 のよくある質問  /  MySQL 5.6 FAQ: MySQL の中国語、日本語、および韓国語の文字セット

A.11 MySQL 5.6 FAQ: MySQL の中国語、日本語、および韓国語の文字セット

この一連のよくある質問は、CJK (中国語、日本語、韓国語) の問題に関する多くの問い合わせに対応している MySQL のサポートグループおよび開発グループの経験から得られたものです。

A.11.1. MySQL で使用できる CJK 文字セットはどの文字セットですか。
A.11.2. CJK 文字をテーブルに挿入しました。SELECT でそれらが「?」文字として表示されるのはなぜですか。
A.11.3. Big5 中国語文字セットを使用する場合は、どのような問題に注意するべきですか。
A.11.4. 日本語文字セットの変換が失敗するのはなぜですか。
A.11.5. SJIS の 81CA を cp932 に変換する場合はどうすればよいですか。
A.11.6. MySQL では円 (¥) 記号をどのように表しますか。
A.11.7. MySQL には、5C が円記号である別の文字セットを作成する計画はありますか。ほかの主要な DBMS の少なくとも 1 つにはそれがあります。
A.11.8. MySQL で韓国語文字セットを使用する場合に注意する問題はありますか。
A.11.9. なぜ「Incorrect string value」というエラーメッセージが表示されるのですか。
A.11.10. Access、PHP、またはその他の API を使用したアプリケーションの GUI フロントエンドまたはブラウザで、CJK 文字が正しく表示されないのはなぜですか。
A.11.11. MySQL 5.6 にアップグレードしました。文字セットに関して、MySQL 4.0 の動作に戻すにはどうすればよいですか。
A.11.12. CJK 文字での LIKE 検索および FULLTEXT 検索が失敗することがあるのはなぜですか。
A.11.13. 文字 X がすべての文字セットで使用可能であるかどうかを判別するにはどうすればよいですか。
A.11.14. CJK 文字列が Unicode で間違ってソートされるのはなぜですか。(I)
A.11.15. CJK 文字列が Unicode で間違ってソートされるのはなぜですか。(II)
A.11.16. 補助文字が MySQL で拒否されるのはなぜですか。
A.11.17. 「CJKV」にするべきではありませんか。
A.11.18. MySQL では CJK 文字をデータベース名およびテーブル名に使用できますか。
A.11.19. MySQL マニュアルの中国語版、日本語版、および韓国語版はどこにありますか。
A.11.20. MySQL での CJK および関連する問題についての支援はどこで受けることができますか。

A.11.1.

MySQL で使用できる CJK 文字セットはどの文字セットですか。

CJK 文字セットのリストは、MySQL のバージョンによって異なることがあります。たとえば、gb18030 文字セットは MySQL 5.7.4 より前はサポートされていませんでした。ただし、INFORMATION_SCHEMA.CHARACTER_SETS 表のすべてのエントリの DESCRIPTION カラムには適用可能な言語の名前が表示されるため、次のクエリーを使用して Unicode 以外のすべての CJK 文字セットの最新のリストを取得できます。

mysql> SELECT CHARACTER_SET_NAME, DESCRIPTION
    -> FROM INFORMATION_SCHEMA.CHARACTER_SETS
    -> WHERE DESCRIPTION LIKE '%Chin%'
    -> OR DESCRIPTION LIKE '%Japanese%'
    -> OR DESCRIPTION LIKE '%Korean%'
    -> ORDER BY CHARACTER_SET_NAME;
+--------------------+---------------------------------+
| CHARACTER_SET_NAME | DESCRIPTION                     |
+--------------------+---------------------------------+
| big5               | Big5 Traditional Chinese        |
| cp932              | SJIS for Windows Japanese       |
| eucjpms            | UJIS for Windows Japanese       |
| euckr              | EUC-KR Korean                   |
| gb18030            | China National Standard GB18030 |
| gb2312             | GB2312 Simplified Chinese       |
| gbk                | GBK Simplified Chinese          |
| sjis               | Shift-JIS Japanese              |
| ujis               | EUC-JP Japanese                 |
+--------------------+---------------------------------+
9 rows in set (0.01 sec)

(詳細は、セクション21.1「INFORMATION_SCHEMA CHARACTER_SETS テーブル」を参照してください。)

MySQL は中華人民共和国の正式な文字セットである GB 文字セット (Guojia BiaozhunNational Standard、または Simplified Chinese) の 3 つのバリアント (gb2312gbk、および gb18030 (MySQL 5.7.4 で追加されました)) をサポートしています。

ユーザーが gbk の文字を gb2312 に挿入しようとすることがありますが、これはほとんどの場合動作します。gbkgb2312 のスーパーセットであるためです。ただし、より珍しい漢字を挿入しようとすると動作しません。(例については、Bug #16072 を参照してください)。

ここでは、gb2312 または gbk で正当な文字を明らかにして、正式なドキュメントへの参照を示します。gb2312 または gbk のバグを報告する前に、これらのリファレンスを確認してください。

  • gb2312_chinese_ci 照合順序に従って並べられた gb2312 文字の完全なリストについては、gb2312 を参照してください。

  • MySQL の gbk は、実際にはMicrosoft コードページ 936です。これは、正式な gbk とは文字 A1A4 (中黒)、A1AA (エムダッシュ)、A6E0-A6F5、および A8BB-A8C0 が異なります。

  • gbk/Unicode マッピングのリストについては、http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT を参照してください。

  • MySQL の gbk 文字のリストについては、gbk を参照してください。

A.11.2.

CJK 文字をテーブルに挿入しました。SELECT でそれらが?文字として表示されるのはなぜですか。

この問題は、通常、アプリケーションプログラムまたはオペレーティングシステムの設定と MySQL の設定が一致していないことが原因です。これらのタイプの問題を修正するための一般的な手順を次に示します。

  • 使用している MySQL のバージョンを確認します

    これを判別するには、SELECT VERSION(); ステートメントを使用します。

  • 意図した文字セットがデータベースで実際に使用されていることを確認します

    ユーザーは多くの場合、クライアントの文字セットはサーバーの文字セットまたは表示のために使用される文字セットと常に同じであると考えます。ただし、これらは両方とも間違った想定です。SHOW CREATE TABLE tablename の結果をチェックするか、次のステートメントを使用することによって確認できます。

    SELECT character_set_name, collation_name
        FROM information_schema.columns
        WHERE table_schema = your_database_name
            AND table_name = your_table_name
            AND column_name = your_column_name;
    
  • 正しく表示されない文字の 16 進値を判別します

    テーブル table_name のカラム column_name のこの情報を取得するには、次のクエリーを使用します。

    SELECT HEX(column_name)
    FROM table_name;
    

    3F? 文字のエンコードです。これは、? が実際にカラムに格納される文字であることを意味します。これは、ほとんどの場合、特定の文字をクライアントの文字セットからターゲットの文字セットに変換するときの問題のために発生します。

  • ラウンドトリップが可能であることを確認します (つまり、literal (または _introducer hexadecimal-value) を選択すると、結果として literal が取得される)

    たとえば、日本語のカタカナ文字 Pe () はすべての CJK 文字セットに存在し、コードポイント値 (16 進コーディング) は 0x30da です。この文字のラウンドトリップをテストするには、次のクエリーを使用します。

    SELECT 'ペ' AS `ペ`;         /* or SELECT _ucs2 0x30da; */
    

    結果も「ペ」ではない場合、ラウンドトリップは失敗しました。

    そのような失敗に関するバグレポートの場合は、SELECT HEX('ペ'); も試すように要請されることがあります。これにより、クライアントのエンコードが正しいかどうかを判断できます。

  • 問題が MySQL 以外のブラウザまたはほかのアプリケーションの問題ではないことを確認します

    このタスクを行うには、mysql クライアントプログラム (Windows の場合: mysql.exe) を使用します。mysql では正しく表示されるが、アプリケーションでは表示されない場合、問題はシステム設定が原因である可能性があります。

    設定を確認するには、次のような出力が表示される SHOW VARIABLES ステートメントを使用します。

    mysql> SHOW VARIABLES LIKE 'char%';
    +--------------------------+----------------------------------------+
    | Variable_name            | Value                                  |
    +--------------------------+----------------------------------------+
    | character_set_client     | utf8                                   |
    | character_set_connection | utf8                                   |
    | character_set_database   | latin1                                 |
    | character_set_filesystem | binary                                 |
    | character_set_results    | utf8                                   |
    | character_set_server     | latin1                                 |
    | character_set_system     | utf8                                   |
    | character_sets_dir       | /usr/local/mysql/share/mysql/charsets/ |
    +--------------------------+----------------------------------------+
    8 rows in set (0.03 sec)
    

    これらは、西洋諸国のサーバー (latin1 は西ヨーロッパ文字セットであり、MySQL のデフォルトです) に接続される国際業務用のクライアントの典型的な文字セット設定です (utf8 Unicode が使用されています)。

    Latin よりも Unicode (通常、Unix での utf8 バリアント、および Windows での ucs2 バリアント) の方が望ましいですが、オペレーティングシステムのユーティリティーで最適にサポートされる文字セットではないことがあります。多くの Windows ユーザーは、Microsoft の文字セット (日本語 Windows 用の cp932 など) が適当であると判断します。

    サーバーの設定を制御できず、基盤となっているコンピュータがわからない場合は、自分の国の一般的な文字セットに変更することを試してください (euckr = 韓国、gb18030gb2312、または gbk = 中華人民共和国、big5 = 台湾、sjisujiscp932、または eucjpms = 日本、ucs2 または utf8 = すべての国)。通常、クライアント、接続、および結果の設定のみを変更する必要があります。この 3 つを一度にすべて変更する簡単なステートメントがSET NAMES です。例:

    SET NAMES 'big5';
    

    設定が正しい場合は、my.cnf または my.ini を編集することによってそれを永続的なものにできます。たとえば、次のような行を追加できます。

    [mysqld]
    character-set-server=big5
    [client]
    default-character-set=big5
    

    アプリケーションで使用されている API 構成の設定に問題があることもあります。詳細は、「GUI フロントエンドまたはブラウザで CJK 文字が正しく表示されないのはなぜですか」を参照してください。

A.11.3.

Big5 中国語文字セットを使用する場合は、どのような問題に注意するべきですか。

MySQL は、香港および台湾 (中華民国) で一般的な Big5 文字セットをサポートしています。MySQL の big5 は、実際には、本来の big5 文字セットと非常に似ている Microsoft コードページ 950 です。この文字セットは MySQL バージョン 4.1.16 / 5.0.16 以降で変更されています (Bug #12476 のため)。たとえば、次のステートメントは最新のバージョンの MySQL では動作しますが、古いバージョンでは動作しません。

mysql> CREATE TABLE big5 (BIG5 CHAR(1) CHARACTER SET BIG5);
Query OK, 0 rows affected (0.13 sec)

mysql> INSERT INTO big5 VALUES (0xf9dc);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM big5;
+------+
| big5 |
+------+
| 嫺  |
+------+
1 row in set (0.02 sec)

HKSCS 拡張を追加する機能要求は申請されています。この拡張を必要とするユーザーの場合、Bug #13577 のための推奨パッチが役に立つことがあります。

A.11.4.

日本語文字セットの変換が失敗するのはなぜですか。

MySQL は、sjisujiscp932、および eucjpms 文字セットと Unicode をサポートしています。一般的なニーズは文字セット間で変換を行うことです。たとえば、Unix のサーバー (通常は sjis または ujis が使用されます) と Windows のクライアント (通常は cp932 が使用されます) を使用している場合があります。

次の変換表で、ucs2 カラムは変換前を表し、sjiscp932ujis、および eucjpms カラムは変換後を表しています。つまり、後ろの 4 つのカラムは、CONVERT(ucs2) を使用するか、値が含まれている ucs2 カラムを sjiscp932ujis、または eucjpms カラムに割り当てたときの 16 進数の結果を示しています。

文字名 ucs2 sjis cp932 ujis eucjpms
BROKEN BAR (破断線) 00A6 3F 3F 8FA2C3 3F
FULLWIDTH BROKEN BAR (全角破断線) FFE4 3F FA55 3F 8FA2
YEN SIGN (円記号) 00A5 3F 3F 20 3F
FULLWIDTH YEN SIGN (全角円記号) FFE5 818F 818F A1EF 3F
TILDE (チルダ) 007E 7E 7E 7E 7E
OVERLINE (オーバーライン) 203E 3F 3F 20 3F
HORIZONTAL BAR (水平線) 2015 815C 815C A1BD A1BD
EM DASH (エムダッシュ) 2014 3F 3F 3F 3F
REVERSE SOLIDUS (リバースソリダス) 005C 815F 5C 5C 5C
FULLWIDTH "" (全角リバースソリダス) FF3C 3F 815F 3F A1C0
WAVE DASH (波ダッシュ) 301C 8160 3F A1C1 3F
FULLWIDTH TILDE (全角チルダ) FF5E 3F 8160 3F A1C1
DOUBLE VERTICAL LINE (双柱) 2016 8161 3F A1C2 3F
PARALLEL TO (平行) 2225 3F 8161 3F A1C2
MINUS SIGN (マイナス記号) 2212 817C 3F A1DD 3F
FULLWIDTH HYPHEN-MINUS (全角ハイフンマイナス) FF0D 3F 817C 3F A1DD
CENT SIGN (セント記号) 00A2 8191 3F A1F1 3F
FULLWIDTH CENT SIGN (全角セント記号) FFE0 3F 8191 3F A1F1
POUND SIGN (ポンド記号) 00A3 8192 3F A1F2 3F
FULLWIDTH POUND SIGN (全角ポンド記号) FFE1 3F 8192 3F A1F2
NOT SIGN (否定記号) 00AC 81CA 3F A2CC 3F
FULLWIDTH NOT SIGN (全角否定記号) FFE2 3F 81CA 3F A2CC

では、この表の次の部分について考えてみましょう。

  ucs2 sjis cp932
NOT SIGN (否定記号) 00AC 81CA 3F
FULLWIDTH NOT SIGN (全角否定記号) FFE2 3F 81CA

これは、MySQL が NOT SIGN (Unicode の U+00AC) を sjis のコードポイント 0x81CA および cp932 のコードポイント 3F に変換することを意味します (3F は疑問符 (?) であり、変換を実行できないときに常に使用される文字です)。

A.11.5.

SJIS の 81CAcp932 に変換する場合はどうすればよいですか。

答えは?です。これについては深刻な苦情が寄せられています。多くのユーザーは、sjis81CA (NOT SIGN)cp93281CA (FULLWIDTH NOT SIGN) になるような緩い変換を望んでいます。この動作に変更することが検討されています。

A.11.6.

MySQL では円 (¥) 記号をどのように表しますか。

いくつかのバージョンの日本語文字セット (sjis および euc の両方) では 5Cリバースソリダス (\。バックスラッシュとも呼ばれます) として扱われ、ほかの文字セットでは円記号 (¥) として扱われるため、問題が発生します。

MySQL は JIS (Japanese Industrial Standards) 標準に記述されている 1 つのバージョンのみに従っています。MySQL では 5C は常にリバースソリダス (\) です。

A.11.7.

MySQL には、5C が円記号である別の文字セットを作成する計画はありますか。ほかの主要な DBMS の少なくとも 1 つにはそれがあります。

これは円記号の問題に対する考えられる解決策の 1 つです。ただし、MySQL 5.1 または 6.0 ではこれは対応されません。

A.11.8.

MySQL で韓国語文字セットを使用する場合に注意する問題はありますか。

理論的には、複数のバージョンの euckr (Extended Unix Code Korea) 文字セットがありますが、認識されている問題は 1 つだけです。

コードポイント 0x5cウォン記号 () である EUC-KR のKS-Romanバリアントではなく、コードポイント 0x5c がリバースソリダス (つまり、\) である EUC-KR のASCIIバリアントが使用されています。これは、Unicode の U+20A9euckr に変換できないことを意味します。

mysql> SELECT
    ->     CONVERT('₩' USING euckr) AS euckr,
    ->     HEX(CONVERT('₩' USING euckr)) AS hexeuckr;
+-------+----------+
| euckr | hexeuckr |
+-------+----------+
| ?     | 3F       |
+-------+----------+
1 row in set (0.00 sec)

MySQL のグラフィカルな韓国語チャートについては、euckr を参照してください。

A.11.9.

なぜ「Incorrect string value」というエラーメッセージが表示されるのですか。

説明のために、1 つの Unicode (ucs2) カラムおよび 1 つの中国語 (gb2312) カラムを持つテーブルを作成します。

mysql> CREATE TABLE ch
    -> (ucs2 CHAR(3) CHARACTER SET ucs2,
    -> gb2312 CHAR(3) CHARACTER SET gb2312);
Query OK, 0 rows affected (0.05 sec)

両方のカラムに珍しい文字「汌」を挿入することを試みます。

mysql> INSERT INTO ch VALUES ('A汌B','A汌B');
Query OK, 1 row affected, 1 warning (0.00 sec)

警告が報告されました。次のステートメントを使用してその内容を確認します。

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Warning
   Code: 1366
Message: Incorrect string value: '\xE6\xB1\x8CB' for column 'gb2312' at row 1
1 row in set (0.00 sec)

gb2312 カラムのみに関する警告でした。

mysql> SELECT ucs2,HEX(ucs2),gb2312,HEX(gb2312) FROM ch;
+-------+--------------+--------+-------------+
| ucs2  | HEX(ucs2)    | gb2312 | HEX(gb2312) |
+-------+--------------+--------+-------------+
| A汌B | 00416C4C0042 | A?B    | 413F42      |
+-------+--------------+--------+-------------+
1 row in set (0.00 sec)

いくつかのことを説明する必要があります。

  1. エラーではなく警告であることが MySQL の特徴です。あきらめずにできることをして最善の結果を得ることが試みられます。

  2. 「汌」という文字は gb2312 文字セットにありません。この問題については前に説明しました。

  3. 古いバージョンの MySQL を使用している場合は、別のメッセージが表示される可能性があります。

  4. sql_mode=TRADITIONAL を設定している場合は、警告ではなくエラーメッセージが表示されます。

A.11.10.

Access、PHP、またはその他の API を使用したアプリケーションの GUI フロントエンドまたはブラウザで、CJK 文字が正しく表示されないのはなぜですか。

mysql クライアント (Windows: mysql.exe) を使用してサーバーに直接接続し、同じクエリーをそこで試してください。mysql が正常に応答する場合、問題はアプリケーションインタフェースで初期化が必要であることである可能性があります。mysqlSHOW VARIABLES LIKE 'char%'; ステートメント使用して、使用される文字セットを確認します。Access を使用している場合は、Connector/ODBC を使用して接続することがほとんどです。この場合は、Configuring Connector/ODBCを確認してください。たとえば、big5 を使用している場合は、SET NAMES 'big5' と入力します。(この場合「;」は必要ありません)。ASP を使用している場合は、コードに SET NAMES を追加する必要があることがあります。過去に作成された例を次に示します。

<%
Session.CodePage=0
Dim strConnection
Dim Conn
strConnection="driver={MySQL ODBC 3.51 Driver};server=server;uid=username;" \
               & "pwd=password;database=database;stmt=SET NAMES 'big5';"
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open strConnection
%>

同様に、Connector/Net で latin1 以外の文字セットを使用している場合は、接続文字列に文字セットを指定する必要があります。詳細は、Connecting to MySQL Using Connector/Netを参照してください。

PHP を使用している場合は、次のコードを試してください。

<?php
  $link = mysql_connect($host, $usr, $pwd);

  mysql_select_db($db);

  if( mysql_error() ) { print "Database ERROR: " . mysql_error(); }
  mysql_query("SET NAMES 'utf8'", $link);
?>

この場合、SET NAMES を使用して character_set_clientcharacter_set_connection、および character_set_results を変更しています。

mysql ではなく、新しい mysqli 拡張を使用することをお勧めします。mysqli を使用する場合は、前の例を次のように書き直すことができます。

<?php
  $link = new mysqli($host, $usr, $pwd, $db);

  if( mysqli_connect_errno() )
  {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
  }

  $link->query("SET NAMES 'utf8'");
?>

PHP アプリケーションで頻繁に発生する別の問題は、ブラウザによって行われる想定に関連しています。<meta> タグを追加または変更するだけでこの問題が修正されることがあります。たとえば、ユーザーエージェントがページの内容を UTF-8 として解釈するようにするには、HTML ページの <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"> を含めてください。

Connector/J を使用している場合は、Using Character Sets and Unicodeを参照してください。

A.11.11.

MySQL 5.6 にアップグレードしました。文字セットに関して、MySQL 4.0 の動作に戻すにはどうすればよいですか。

MySQL バージョン 4.0 では、サーバーおよびクライアントの両方のための単一のグローバル文字セットがあり、使用する文字の決定はサーバー管理者が行なっていました。これは MySQL バージョン 4.1 以降で変更されました。現在行われるのは、セクション10.1.4「接続文字セットおよび照合順序」に説明されているように、ハンドシェイクです。

クライアントが接続するときに、使用する文字セットの名前をサーバーに送信します。サーバーはこの名前を使用して、character_set_clientcharacter_set_results、および character_set_connection システム変数を設定します。実際には、サーバーは文字セット名を使用して SET NAMES 操作を実行します。

このことの影響は、--character-set-server=utf8 を指定して mysqld を開始することによって、クライアントの文字セットを制御できないことです。ただし、アジア地域には MySQL 4.0 の動作が望ましいという顧客がいます。この動作を維持できるように、--skip-character-set-client-handshake を使用してオフにできる mysqld スイッチ --character-set-client-handshake が追加されました。--skip-character-set-client-handshake を指定して mysqld を起動すると、クライアントが接続するときに、使用する文字セットの名前がサーバーに送信されますが、サーバーはクライアントからのこの要求を無視します

例として、望ましいサーバーの文字セットが latin1 であるとします (CJK 地域ではあまりないことですが、これはデフォルト値です)。クライアントのオペレーティングシステムでサポートされている文字セットであるため、クライアントが utf8 を使用しているとします。latin1 をデフォルトの文字セットとしてサーバーを起動します。

mysqld --character-set-server=latin1

そのあと、クライアントをデフォルトの文字セット utf8 で起動します。

mysql --default-character-set=utf8

現在の設定は、SHOW VARIABLES の出力を表示することによって確認できます。

mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------------------+
| Variable_name            | Value                                  |
+--------------------------+----------------------------------------+
| character_set_client     | utf8                                   |
| character_set_connection | utf8                                   |
| character_set_database   | latin1                                 |
| character_set_filesystem | binary                                 |
| character_set_results    | utf8                                   |
| character_set_server     | latin1                                 |
| character_set_system     | utf8                                   |
| character_sets_dir       | /usr/local/mysql/share/mysql/charsets/ |
+--------------------------+----------------------------------------+
8 rows in set (0.01 sec)

クライアントを停止し、mysqladmin を使用してサーバーを停止します。今度はハンドシェイクをスキップするように通知して、サーバーをふたたび起動します。

mysqld --character-set-server=utf8 --skip-character-set-client-handshake

クライアントをデフォルトの文字セットとして utf8 をふたたび指定して起動し、現在の設定を表示します。

mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------------------+
| Variable_name            | Value                                  |
+--------------------------+----------------------------------------+
| character_set_client     | latin1                                 |
| character_set_connection | latin1                                 |
| character_set_database   | latin1                                 |
| character_set_filesystem | binary                                 |
| character_set_results    | latin1                                 |
| character_set_server     | latin1                                 |
| character_set_system     | utf8                                   |
| character_sets_dir       | /usr/local/mysql/share/mysql/charsets/ |
+--------------------------+----------------------------------------+
8 rows in set (0.01 sec)

SHOW VARIABLES の異なる結果を比較することによって確認できるように、--skip-character-set-client-handshake が使用された場合、サーバーはクライアントの初期設定を無視します。

A.11.12.

CJK 文字での LIKE 検索および FULLTEXT 検索が失敗することがあるのはなぜですか。

BINARY カラムおよび BLOB カラムに対する LIKE 検索には非常に単純な問題があります。文字の終わりを判別する必要があることです。マルチバイト文字セットでは、各文字のオクテット長が異なることがあります。たとえば、utf8 の場合、次に示すように A は 1 バイトを必要としますが、 は 3 バイトを必要とします。

+-------------------------+---------------------------+
| OCTET_LENGTH(_utf8 'A') | OCTET_LENGTH(_utf8 'ペ') |
+-------------------------+---------------------------+
|                       1 |                         3 |
+-------------------------+---------------------------+
1 row in set (0.00 sec)

最初の文字の終わりを判別できなければ、2 番目の文字が始まる位置を判別できません。この場合、LIKE '_A%' などの非常に単純な検索が失敗します。解決策は、通常の CJK 文字セットを最初から使用するか、比較する前に CJK 文字を変換することです。

これは、存在しない文字のエンコードを MySQL が許可できない理由の 1 つです。不正な入力を厳密に拒否しなければ、文字の終わりを判別する方法がありません。

FULLTEXT 検索の場合は、単語の始まりと終わりを判別する必要があります。西洋の言語の場合、それらのほとんど (すべてでなければ) が簡単に識別できる単語の境界 (スペース文字) を使用しているため、これが問題となることはほとんどありません。ただし、通常、アジアの言語ではこれは異なります。独自の判断で不完全な方法を使用して、すべての漢字が単語を表すと想定したり、(日本語の場合) 文法的な終わりに従ったカタカナからひらがなへの変化に応じるようにしたりすることもできます。ただし、唯一の確実な解決策では、包括的な単語のリストが必要となります。これは、サポートされる各アジア言語のサーバーに辞書を含める必要があることを意味します。これは簡単に言って実現可能ではありません。

A.11.13.

文字 X がすべての文字セットで使用可能であるかどうかを判別するにはどうすればよいですか。

簡体字中国語および半角ではない基本的な日本語のかな文字のほとんどは、すべての CJK 文字セットで表示されます。次のストアドプロシージャーは、UCS-2 Unicode 文字を受け入れて、それをほかのすべての文字セットに変換し、結果を 16 進数で表示します。

DELIMITER //

CREATE PROCEDURE p_convert(ucs2_char CHAR(1) CHARACTER SET ucs2)
BEGIN

CREATE TABLE tj
             (ucs2 CHAR(1) character set ucs2,
              utf8 CHAR(1) character set utf8,
              big5 CHAR(1) character set big5,
              cp932 CHAR(1) character set cp932,
              eucjpms CHAR(1) character set eucjpms,
              euckr CHAR(1) character set euckr,
              gb2312 CHAR(1) character set gb2312,
              gbk CHAR(1) character set gbk,
              sjis CHAR(1) character set sjis,
              ujis CHAR(1) character set ujis);

INSERT INTO tj (ucs2) VALUES (ucs2_char);

UPDATE tj SET utf8=ucs2,
              big5=ucs2,
              cp932=ucs2,
              eucjpms=ucs2,
              euckr=ucs2,
              gb2312=ucs2,
              gbk=ucs2,
              sjis=ucs2,
              ujis=ucs2;

/* If there is a conversion problem, UPDATE will produce a warning. */

SELECT hex(ucs2) AS ucs2,
       hex(utf8) AS utf8,
       hex(big5) AS big5,
       hex(cp932) AS cp932,
       hex(eucjpms) AS eucjpms,
       hex(euckr) AS euckr,
       hex(gb2312) AS gb2312,
       hex(gbk) AS gbk,
       hex(sjis) AS sjis,
       hex(ujis) AS ujis
FROM tj;

DROP TABLE tj;

END//

入力は、単一の ucs2 文字、またはその文字のコードポイント値 (16 進表記) です。たとえば、ucs2 のエンコードおよび名前についての Unicode のリスト (http://www.unicode.org/Public/UNIDATA/UnicodeData.txt) から、カタカナ文字 Pe はすべての CJK 文字セットにあり、コードポイント値が 0x30da であることがわかります。この値を p_convert() の引数として使用すると、次のような結果となります。

mysql> CALL p_convert(0x30da)//
+------+--------+------+-------+---------+-------+--------+------+------+------+
| ucs2 | utf8   | big5 | cp932 | eucjpms | euckr | gb2312 | gbk  | sjis | ujis |
+------+--------+------+-------+---------+-------+--------+------+------+------+
| 30DA | E3839A | C772 | 8379  | A5DA    | ABDA  | A5DA   | A5DA | 8379 | A5DA |
+------+--------+------+-------+---------+-------+--------+------+------+------+
1 row in set (0.04 sec)

カラム値が 3F (つまり、疑問符文字 (?)) であるカラムがないため、すべての変換が正常に行われたことがわかります。

A.11.14.

CJK 文字列が Unicode で間違ってソートされるのはなぜですか。(I)

utf8_unicode_ci 検索や ucs2_unicode_ci 検索、または ORDER BY ソートの結果が、母国語のユーザーが予期する結果ではないことがあります。バグである可能性を除外するわけではありませんが、多くのユーザーは Unicode Collation Algorithm の標準表のウェイトを正しく読んでいないことが過去に判明しました。MySQL は http://www.unicode.org/Public/UCA/4.0.0/allkeys-4.0.0.txt にある表を使用しています。これは、unicode.org のホームページからナビゲートすることによって見つかる最初の表ではありません。MySQL はより新しい 4.1.0 の allkeys 表ではなく、古い 4.0.0 の表を使用しているためです。(MySQL 5.6 の新しい '520' 照合順序では、5.2 の allkeys 表が使用されています。)これは、次に示した Bug #16526 で報告されたような状況が発生しないように、インデックスに影響する順序付けの変更に非常に慎重であるためです。

mysql< CREATE TABLE tj (s1 CHAR(1) CHARACTER SET utf8 COLLATE utf8_unicode_ci);
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO tj VALUES ('が'),('か');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM tj WHERE s1 = 'か';
+------+
| s1   |
+------+
| が  |
| か  |
+------+
2 rows in set (0.00 sec)

最初の結果行の文字は、検索した文字ではありません。MySQL でその文字が取得されたのはなぜでしょうか。まず、Unicode のコードポイント値を確認します。これを行うには、ucs2 バージョンの文字の 16 進数を表示します。

mysql> SELECT s1, HEX(CONVERT(s1 USING ucs2)) FROM tj;
+------+-----------------------------+
| s1   | HEX(CONVERT(s1 USING ucs2)) |
+------+-----------------------------+
| が  | 304C                        |
| か  | 304B                        |
+------+-----------------------------+
2 rows in set (0.03 sec)

4.0.0 allkeys 表で 304B および 304C を探すと、これらの行が見つかります。

304B  ; [.1E57.0020.000E.304B] # HIRAGANA LETTER KA
304C  ; [.1E57.0020.000E.304B][.0000.0140.0002.3099] # HIRAGANA LETTER GA; QQCM

正式な Unicode 名 (# マークの後ろにあります) は、日本語の五十音 (ひらがな)、非公式な区分 (文字、数字、または句読点)、西洋言語での識別子 (KA または GA。これは、たまたま同じ文字のペアの有声音および無声音となっています) を示しています。さらに重要なのは、プライマリウェイト (角括弧の中の最初の 16 進数) が両方の行で 1E57 となっていることです。検索とソートの両方の比較で、MySQL はプライマリウェイトのみに注意を払って、ほかのすべての数値を無視します。これは、「が」および「か」が Unicode の仕様に従って正しくソートされていることを意味します。これらを区別するには、UCA (Unicode Collation Algorithm) 以外の照合順序 (utf8_bin または utf8_general_ci) を使用するか、HEX() 値を比較するか、ORDER BY CONVERT(s1 USING sjis) を使用する必要があります。もちろん、Unicode に従えば正しいだけでは十分ではなく、バグを報告したユーザーも同様に正しいと言えます。KA/GA のような有声音/無声音文字のペアを順序付けのために区別できる、JIS X 4061 標準に従った別の日本語の照合順序を追加する計画があります。

A.11.15.

CJK 文字列が Unicode で間違ってソートされるのはなぜですか。(II)

Unicode (ucs2 または utf8) を使用していて、Unicode のソート順がわかっているが (セクションA.11「MySQL 5.6 FAQ: MySQL の中国語、日本語、および韓国語の文字セット」を参照してください)、MySQL でテーブルが間違ってソートされているように見える場合は、まずテーブルの文字セットを確認してください。

mysql> SHOW CREATE TABLE t\G
******************** 1. row ******************
Table: t
Create Table: CREATE TABLE `t` (
`s1` char(1) CHARACTER SET ucs2 DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

文字セットは正しいように見えるため、このカラムに関して INFORMATION_SCHEMA.COLUMNS テーブルで表示できる情報を確認します。

mysql> SELECT COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME
    -> FROM INFORMATION_SCHEMA.COLUMNS
    -> WHERE COLUMN_NAME = 's1'
    -> AND TABLE_NAME = 't';
+-------------+--------------------+-----------------+
| COLUMN_NAME | CHARACTER_SET_NAME | COLLATION_NAME  |
+-------------+--------------------+-----------------+
| s1          | ucs2               | ucs2_general_ci |
+-------------+--------------------+-----------------+
1 row in set (0.01 sec)

(詳細は、セクション21.4「INFORMATION_SCHEMA COLUMNS テーブル」を参照してください。)

照合順序が ucs2_unicode_ci ではなく ucs2_general_ci であることがわかります。このようになる理由は、次のように SHOW CHARSET を使用して見つけることができます。

mysql> SHOW CHARSET LIKE 'ucs2%';
+---------+---------------+-------------------+--------+
| Charset | Description   | Default collation | Maxlen |
+---------+---------------+-------------------+--------+
| ucs2    | UCS-2 Unicode | ucs2_general_ci   |      2 |
+---------+---------------+-------------------+--------+
1 row in set (0.00 sec)

ucs2 および utf8 の場合、デフォルトの照合順序は general です。Unicode の照合順序を指定するには、COLLATE ucs2_unicode_ci を使用します。

A.11.16.

補助文字が MySQL で拒否されるのはなぜですか。

MySQL 5.5.3 より前では、MySQL は補助文字 (つまり、UTF-8 で 3 バイトを超えるサイズを必要とする文字) をサポートしていません。Unicode で基本多言語面/第 0 面と呼ばれているもののみがサポートされます。いくつかの非常に珍しい漢字のみが補助文字となっています。それらに対するサポートは一般的ではありません。このことが Bug #12600 などで報告され、バグではありませんとして拒否されました。utf8 では、理解できないバイトが出現した場合に、入力文字列を切り捨てる必要があります。そうしないと、不正なマルチバイト文字の長さがわかりません。

考えられる 1 つの回避策は、utf8 の代わりに ucs2 を使用することです。この場合、不正な文字は疑問符に置き換えられますが、切り捨ては行われません。妥当性チェックが行われない BLOB または BINARY にデータ型を変更することもできます。

MySQL 5.5.3 の時点では、追加の Unicode 文字セット utf16utf32、および 4 バイトの utf8mb4 によって Unicode のサポートが拡張され、補助文字が含まれるようになりました。これらの文字セットでは、基本多言語面 (BMP) の外にある補助 Unicode 文字がサポートされます。

A.11.17.

CJKVにするべきではありませんか。

いいえ。用語CJKV(Chinese Japanese Korean Vietnamese) は漢字 (もともとは中国語) が含まれているベトナム文字セットを指しています。MySQL では、漢字を使用した古いベトナム文字をサポートする計画はありません。MySQL では、西洋文字を使用する現代のベトナム文字はもちろんサポートされます。

MySQL 5.6 の時点では、セクション10.1.14.1「Unicode 文字セット」で説明しているように、Unicode 文字セットにベトナム語の照合順序があります。

A.11.18.

MySQL では CJK 文字をデータベース名およびテーブル名に使用できますか。

この問題は、対応するディレクトリおよびファイルの名前を自動的に書き換えることによって、MySQL 5.1 で修正されました。

たとえば、オペレーティングシステムでディレクトリ名に CJK がサポートされないサーバーに「楮」という名前のデータベースを作成した場合、MySQL は E6A5AE (つまり、「楮」文字の Unicode の 16 進表現) を特殊な方法でエンコードした @0w@00a5@00ae という名前のディレクトリが作成されます。ただし、SHOW DATABASES ステートメントを実行すると、データベースが「楮」として示されます。

A.11.19.

MySQL マニュアルの中国語版、日本語版、および韓国語版はどこにありますか。

MySQL 5.1.12 の簡体字中国語版のマニュアルは、http://dev.mysql.com/doc/にあります。MySQL 4.1 マニュアルの日本語版は、http://dev.mysql.com/doc/ からダウンロードできます。

A.11.20.

MySQL での CJK および関連する問題についての支援はどこで受けることができますか。

次のリソースを利用できます。


User Comments
Sign Up Login You must be logged in to post a comment.