MySQL 8.0 リファレンスマニュアル


MySQL 8.0 リファレンスマニュアル  /  文字セット、照合順序、Unicode  /  接続文字セットおよび照合順序

10.4 接続文字セットおよび照合順序

connection は、クライアントプログラムがサーバーに接続したときに、サーバーと対話するセッションを開始するために行われるものです。 クライアントは、クエリーなどの SQL ステートメントをセッション接続を介して送信します。 サーバーは接続を介して、結果セットやエラーメッセージなどの応答をクライアントに送信します。

接続文字セットおよび照合順序システム変数

複数の文字セットおよび照合順序のシステム変数は、サーバーとのクライアントの通信に関係しています。 これらのいくつかは、これまでのセクションですでに説明されています。

その他の文字セットおよび照合順序システム変数は、クライアントとサーバー間の接続のトラフィックの処理に関わっています。 すべてのクライアントには、セッション固有の接続関連の文字セットおよび照合順序システム変数があります。 これらのセッションシステム変数値は接続時に初期化されますが、セッション内で変更できます。

クライアント接続の文字セットおよび照合順序処理に関するいくつかの質問には、システム変数の観点から回答できます:

  • クライアントから離れるときのステートメントの文字セットは何ですか。

    サーバーは、character_set_client システム変数値を、クライアントが送信するステートメントの文字セットにします。

    注記

    一部の文字セットは、クライアントの文字セットとして使用できません。 許可されていないクライアント文字セットを参照してください。

  • サーバーがステートメントを受信したあと、どの文字セットに変換するべきですか。

    これを確認するために、サーバーは character_set_connection および collation_connection システム変数を使用します:

    • サーバーは、クライアントによって送信されたステートメントを character_set_client から character_set_connection に変換します。 例外: _utf8mb4_latin2 などのイントロデューサを持つ文字列リテラルの場合、イントロデューサは文字セットを決定します。 セクション10.3.8「文字セットイントロデューサ」を参照してください。

    • collation_connection は、リテラル文字列の比較に重要です。 カラム値と文字列を比較する場合、collation_connection は関係ありません。これは、カラムには照合優先度の高い独自の照合があるためです (セクション10.8.4「式での照合の強制性」 を参照)。

  • クエリー結果をクライアントに返送する前に、サーバーはどの文字セットに変換する必要がありますか。

    character_set_results システム変数値は、サーバーがクライアントにクエリー結果を返信するときに使用する文字セットを示します。 これには、カラム値、結果メタデータ (カラム名など)、エラーメッセージなどの結果データが含まれます。

    結果セットまたはエラーメッセージの変換を実行しないようにサーバーに指示するには、character_set_resultsNULL または binary に設定します:

    SET character_set_results = NULL;
    SET character_set_results = binary;

    文字セットおよびエラーメッセージの詳細は、セクション10.6「エラーメッセージ文字セット」を参照してください。

現在のセッションに適用される文字セットおよび照合順序システム変数の値を確認するには、次のステートメントを使用します:

SELECT * FROM performance_schema.session_variables
WHERE VARIABLE_NAME IN (
'character_set_client', 'character_set_connection',
'character_set_results', 'collation_connection'
) ORDER BY VARIABLE_NAME;

次の単純なステートメントでも接続変数が表示されますが、関連する他の変数も含まれます。 これらは、all 文字セットおよび照合順序システム変数の表示に役立ちます:

SHOW SESSION VARIABLES LIKE 'character\_set\_%';
SHOW SESSION VARIABLES LIKE 'collation\_%';

クライアントは、これらの変数の設定を微調整することも、デフォルトに従うこともできます (この場合は、このセクションの残りをスキップできます)。 デフォルトを使用しない場合、サーバーへの接続ごとに文字設定を変更する必要があります。

許可されていないクライアント文字セット

character_set_client システム変数は、特定の文字セットに設定できません:

ucs2
utf16
utf16le
utf32

これらの文字セットのいずれかをクライアント文字セットとして使用しようとすると、エラーが発生します:

mysql> SET character_set_client = 'ucs2';
ERROR 1231 (42000): Variable 'character_set_client'
can't be set to the value of 'ucs2'

これらの文字セットのいずれかが次のコンテキストで使用されている場合、同じエラーが発生し、その結果、character_set_client に名前付き文字セットを設定しようとします:

  • mysqlmysqladmin などの MySQL クライアントプログラムで使用される --default-character-set=charset_name コマンドオプション。

  • SET NAMES 'charset_name'ステートメント。

  • SET CHARACTER SET 'charset_name'ステートメント。

クライアントプログラム接続文字セット構成

クライアントがサーバーに接続すると、サーバーとの通信に使用する文字セットが示されます。 (実際には、クライアントはその文字セットのデフォルトの照合順序を示し、サーバーはこの照合順序から文字セットを決定できます。) サーバーは、この情報を使用して character_set_client, character_set_results, character_set_connection システム変数を文字セットに設定し、collation_connection を文字セットのデフォルトの照合順序に設定します。 実際には、サーバーは SET NAMES 操作と同等の処理を実行します。

サーバーが要求された文字セットまたは照合順序をサポートしていない場合は、サーバー文字セットおよび照合順序を使用して接続を構成します。 このフォールバック動作の詳細は、接続文字セットのエラー処理 を参照してください。

mysql, mysqladmin, mysqlcheck, mysqlimport および mysqlshow クライアントプログラムは、使用するデフォルトの文字セットを次のように決定します:

  • その他の情報がない場合、各クライアントはコンパイルされたデフォルト文字セット (通常は utf8mb4) を使用します。

  • 各クライアントは、Unix システムの LANG または LC_ALL ロケール環境変数の値や Windows システムのコードページ設定など、オペレーティングシステムの設定に基づいて、使用する文字セットを自動検出できます。 ロケールが OS から利用できるシステムの場合、クライアントはコンパイル時のデフォルトを使用するのではなく、このロケールを使用してデフォルトの文字セットを設定します。 たとえば、LANGru_RU.KOI8-R に設定すると、koi8r 文字セットが使用されます。 したがってユーザーは、MySQL クライアントが使用できるように、自身の環境内でロケールを構成できます。

    OS 文字セットは、正確に一致するものがない場合は、もっとも近い MySQL 文字セットにマップされます。 一致した文字セットをサポートしていない場合、クライアントはコンパイルイ時のデフォルトを使用します。 たとえば、utf8 および utf-8utf8mb4 にマップされ、ucs2 は接続文字セットとしてサポートされていないため、コンパイル済のデフォルトにマップされます。

    C アプリケーションは、サーバーに接続する前に次のように mysql_options() を呼び出すことによって、OS 設定に基づいて文字セットの自動検出を使用できます。

    mysql_options(mysql,
                  MYSQL_SET_CHARSET_NAME,
                  MYSQL_AUTODETECT_CHARSET_NAME);
  • 各クライアントは --default-character-set オプションをサポートしているため、ユーザーは文字セットを明示的に指定して、それ以外の場合にクライアントが決定するデフォルトをオーバーライドできます。

    注記

    一部の文字セットは、クライアントの文字セットとして使用できません。 --default-character-set でこれらを使用しようとすると、エラーが発生します。 許可されていないクライアント文字セットを参照してください。

mysql クライアントでは、デフォルトとは異なる文字セットを使用するために、サーバーに接続するたびに SET NAMES ステートメントを明示的に実行できます (クライアントプログラム接続文字セット構成 を参照)。 同じ結果をより簡単に得るには、オプションファイルに文字セットを指定します。 たとえば、次のオプションファイル設定では、mysql を起動するたびに、接続関連の 3 つの文字セットシステム変数が koi8r に設定されます:

[mysql]
default-character-set=koi8r

自動再接続を有効にして mysql クライアントを使用している場合は (推奨しません)、SET NAMES ではなく charset コマンドを使用することをお勧めします。 例:

mysql> charset koi8r
Charset changed

charset コマンドは、SET NAMES ステートメントを発行し、接続の切断後に再接続するときに mysql が使用するデフォルトの文字セットも変更します。

クライアントプログラムを構成する場合は、クライアントプログラムが実行される環境も考慮する必要があります。 セクション10.5「アプリケーションの文字セットおよび照合順序の構成」を参照してください。

接続文字セット構成用の SQL ステートメント

接続が確立されると、クライアントは現在のセッションの文字セットおよび照合順序システム変数を変更できます。 これらの変数は SET ステートメントを使用して個別に変更できますが、接続関連の文字セットシステム変数にグループとして影響する便利なステートメントは 2 つあります:

  • SET NAMES 'charset_name' [COLLATE 'collation_name']

    SET NAMES は、クライアントが SQL ステートメントをサーバーに送信するために使用する文字セットを示します。 したがって、SET NAMES 'cp1251' は、このクライアントから今後受信するメッセージが文字セット cp1251 で送信されることを、サーバーに知らせます。 また、クライアントに結果を返信するときにサーバーが使用する文字セットも指定します。 (たとえば、結果セットを生成する SELECT ステートメントを使用する場合、どの文字セットをカラム値に使用するかを示します。)

    SET NAMES 'charset_name' ステートメントは次の 3 つのステートメントと同等です。

    SET character_set_client = charset_name;
    SET character_set_results = charset_name;
    SET character_set_connection = charset_name;

    character_set_connectioncharset_name に設定すると、collation_connection も暗黙的に charset_name のデフォルト照合順序に設定されます。 この照合順序を明示的に設定する必要はありません。 collation_connection に使用する特定の照合を指定するには、COLLATE 句を追加します:

    SET NAMES 'charset_name' COLLATE 'collation_name'
  • SET CHARACTER SET 'charset_name'

    SET CHARACTER SETSET NAMES と似ていますが、character_set_connection および collation_connectioncharacter_set_database および collation_database に設定します (前述のように、デフォルトデータベースの文字セットおよび照合順序を示します)。

    SET CHARACTER SET charset_name ステートメントは次の 3 つのステートメントと同等です。

    SET character_set_client = charset_name;
    SET character_set_results = charset_name;
    SET collation_connection = @@collation_database;

    collation_connection を設定すると、character_set_connection も、関連付けられた文字セットに暗黙的に設定されます (SET character_set_connection = @@character_set_database の実行と同等です)。 character_set_connection を明示的に設定する必要はありません。

注記

一部の文字セットは、クライアントの文字セットとして使用できません。 SET NAMES または SET CHARACTER SET でこれらを使用しようとすると、エラーが発生します。 許可されていないクライアント文字セットを参照してください。

例: column1CHAR(5) CHARACTER SET latin2 として定義されているとします。 SET NAMES または SET CHARACTER SET を指定しない場合、SELECT column1 FROM t に対して、サーバーは、接続時にクライアントが指定した文字セットを使用して、column1 のすべての値を送り返します。 一方、SELECT ステートメントを発行する前に SET NAMES 'latin1'または SET CHARACTER SET 'latin1'と言うと、サーバーは結果を返送する直前に latin2 値を latin1 に変換します。 両方の文字セットにない文字の変換は失われる可能性があります。

接続文字セットのエラー処理

不適切な接続文字セットまたは照合順序を使用しようとすると、エラーが発生するか、サーバーが特定の接続のデフォルトの文字セットおよび照合順序にフォールバックする可能性があります。 このセクションでは、接続文字セットの構成時に発生する可能性のある問題について説明します。 これらの問題は、接続を確立するとき、または確立された接続内の文字セットを変更するときに発生することがあります。

接続時のエラー処理

一部の文字セットは、クライアント文字セットとして使用できません。許可されていないクライアント文字セット を参照してください。 有効だがクライアント文字セットとして許可されていない文字セットを指定すると、サーバーはエラーを返します:

shell> mysql --default-character-set=ucs2
ERROR 1231 (42000): Variable 'character_set_client' can't be set to
the value of 'ucs2'

クライアントが認識しない文字セットを指定すると、エラーが発生します:

shell> mysql --default-character-set=bogus
mysql: Character set 'bogus' is not a compiled character set and is
not specified in the '/usr/local/mysql/share/charsets/Index.xml' file
ERROR 2019 (HY000): Can't initialize character set bogus
(path: /usr/local/mysql/share/charsets/)

クライアントが認識するがサーバーが認識しない文字セットを指定した場合、サーバーはデフォルトの文字セットおよび照合順序にフォールバックします。 サーバーが latin1 および latin1_swedish_ci をデフォルトとして使用するように構成されており、gb18030 が有効な文字セットとして認識されないとします。 --default-character-set=gb18030 を指定するクライアントはサーバーに接続できますが、結果の文字セットはクライアントが希望する文字セットではありません:

mysql> SHOW SESSION VARIABLES LIKE 'character\_set\_%';
+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| character_set_client     | latin1 |
| character_set_connection | latin1 |
...
| character_set_results    | latin1 |
...
+--------------------------+--------+
mysql> SHOW SESSION VARIABLES LIKE 'collation_connection';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
+----------------------+-------------------+

接続システム変数が、latin1 および latin1_swedish_ci の文字セットおよび照合順序を反映するように設定されていることがわかります。 これは、サーバーがクライアント文字セットリクエストを満たすことができず、デフォルトに戻すために発生します。

この場合、サーバーがサポートしていないため、クライアントは必要な文字セットを使用できません。 クライアントは、別の文字セットを使用するか、目的の文字セットをサポートする別のサーバーに接続する必要があります。

同じ問題がより微妙なコンテキストで発生: クライアントがサーバーが認識する文字セットを使用するようにサーバーに指示したが、クライアント側のその文字セットのデフォルトの照合順序がサーバー側で認識されない場合。 これは、たとえば、MySQL 8.0 クライアントが utf8mb4 をクライアント文字セットとして使用して MySQL 5.7 サーバーに接続する場合に発生します。 --default-character-set=utf8mb4 を指定するクライアントは、サーバーに接続できます。 ただし、前の例と同様に、サーバーはクライアントが要求した文字セットと照合順序ではなく、デフォルトの文字セットと照合順序にフォールバックします:

mysql> SHOW SESSION VARIABLES LIKE 'character\_set\_%';
+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| character_set_client     | latin1 |
| character_set_connection | latin1 |
...
| character_set_results    | latin1 |
...
+--------------------------+--------+
mysql> SHOW SESSION VARIABLES LIKE 'collation_connection';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
+----------------------+-------------------+

これが発生するのはなぜですか。 その後、utf8mb4 は 8.0 クライアントと 5.7 サーバーに認識されるため、両方で認識されます。 この動作を理解するには、クライアントが使用する文字セットをサーバーに通知するときに、その文字セットのデフォルト照合順序をサーバーに実際に通知することを理解する必要があります。 したがって、前述の動作はファクタの組合せによって発生します:

  • utf8mb4 のデフォルトの照合は、MySQL 5.7 と 8.0 (5.7 の場合は utf8mb4_general_ci、8.0 の場合は utf8mb4_0900_ai_ci) で異なります。

  • 8.0 クライアントが utf8mb4 の文字セットをリクエストすると、サーバーに送信されるものがデフォルトの 8.0 utf8mb4 照合 (utf8mb4_0900_ai_ci) になります。

  • utf8mb4_0900_ai_ci は MySQL 8.0 の時点でのみ実装されるため、5.7 サーバーでは認識されません。

  • 5.7 サーバーは utf8mb4_0900_ai_ci を認識しないため、クライアント文字セットリクエストを満たすことはできず、デフォルトの文字セットおよび照合 (latin1 および latin1_swedish_ci) にフォールバックします。

この場合でも、クライアントは接続後に SET NAMES 'utf8mb4'ステートメントを発行することで utf8mb4 を使用できます。 結果の照合は、5.7 のデフォルトの utf8mb4 照合 (utf8mb4_general_ci) です。 クライアントがさらに utf8mb4_0900_ai_ci の照合を必要とする場合、サーバーはその照合を認識しないため、これを実現できません。 クライアントは、別の utf8mb4 照合を使用するか、MySQL 8.0 以上からサーバーに接続する必要があります。

ランタイムエラー処理

確立された接続内で、クライアントは SET NAMES または SET CHARACTER SET との接続文字セットおよび照合順序の変更をリクエストできます。

一部の文字セットは、クライアント文字セットとして使用できません。許可されていないクライアント文字セット を参照してください。 有効だがクライアント文字セットとして許可されていない文字セットを指定すると、サーバーはエラーを返します:

mysql> SET NAMES 'ucs2';
ERROR 1231 (42000): Variable 'character_set_client' can't be set to
the value of 'ucs2'

サーバーが文字セット (または照合順序) を認識しない場合、エラーが発生します:

mysql> SET NAMES 'bogus';
ERROR 1115 (42000): Unknown character set: 'bogus'

mysql> SET NAMES 'utf8mb4' COLLATE 'bogus';
ERROR 1273 (HY000): Unknown collation: 'bogus'
ヒント

要求された文字セットがサーバーによって適用されたかどうかを確認するクライアントは、接続して結果が予想される文字セットであることを確認したあとに、次のステートメントを実行できます:

SELECT @@character_set_client;

関連キーワード:  文字, セット, 照合, 順序, サーバー, character, 接続, utf, connection, ステートメント