「connection」 は、クライアントプログラムがサーバーに接続したときに、サーバーと対話するセッションを開始するために行われるものです。 クライアントは、クエリーなどの SQL ステートメントをセッション接続を介して送信します。 サーバーは接続を介して、結果セットやエラーメッセージなどの応答をクライアントに送信します。
複数の文字セットおよび照合順序のシステム変数は、サーバーとのクライアントの通信に関係しています。 これらのいくつかは、これまでのセクションですでに説明されています。
character_set_server
およびcollation_server
システム変数は、サーバーの文字セットと照合順序を示します。 セクション10.3.2「サーバー文字セットおよび照合順序」を参照してください。character_set_database
およびcollation_database
システム変数は、デフォルトデータベースの文字セットおよび照合順序を示します。 セクション10.3.3「データベース文字セットおよび照合順序」を参照してください。
その他の文字セットおよび照合順序システム変数は、クライアントとサーバー間の接続のトラフィックの処理に関わっています。 すべてのクライアントには、セッション固有の接続関連の文字セットおよび照合順序システム変数があります。 これらのセッションシステム変数値は接続時に初期化されますが、セッション内で変更できます。
クライアント接続の文字セットおよび照合順序処理に関するいくつかの質問には、システム変数の観点から回答できます:
-
クライアントから離れるときのステートメントの文字セットは何ですか。
サーバーは、
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_results
をNULL
または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
に名前付き文字セットを設定しようとします:
mysql や mysqladmin などの 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 から利用できるシステムの場合、クライアントはコンパイル時のデフォルトを使用するのではなく、このロケールを使用してデフォルトの文字セットを設定します。 たとえば、LANG
をru_RU.KOI8-R
に設定すると、koi8r
文字セットが使用されます。 したがってユーザーは、MySQL クライアントが使用できるように、自身の環境内でロケールを構成できます。OS 文字セットは、正確に一致するものがない場合は、もっとも近い MySQL 文字セットにマップされます。 一致した文字セットをサポートしていない場合、クライアントはコンパイルイ時のデフォルトを使用します。 たとえば、
utf8
およびutf-8
はutf8mb4
にマップされ、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「アプリケーションの文字セットおよび照合順序の構成」を参照してください。
接続が確立されると、クライアントは現在のセッションの文字セットおよび照合順序システム変数を変更できます。 これらの変数は SET
ステートメントを使用して個別に変更できますが、接続関連の文字セットシステム変数にグループとして影響する便利なステートメントは 2 つあります:
-
SET NAMES '
charset_name
' [COLLATE 'collation_name
']SET NAMES
は、クライアントが SQL ステートメントをサーバーに送信するために使用する文字セットを示します。 したがって、SET NAMES 'cp1251'
は、「このクライアントから今後受信するメッセージが文字セットcp1251
で送信される」ことを、サーバーに知らせます。 また、クライアントに結果を返信するときにサーバーが使用する文字セットも指定します。 (たとえば、結果セットを生成するSELECT
ステートメントを使用する場合、どの文字セットをカラム値に使用するかを示します。)SET NAMES '
ステートメントは次の 3 つのステートメントと同等です。charset_name
'SET character_set_client = charset_name; SET character_set_results = charset_name; SET character_set_connection = charset_name;
character_set_connection
をcharset_name
に設定すると、collation_connection
も暗黙的にcharset_name
のデフォルト照合順序に設定されます。 この照合順序を明示的に設定する必要はありません。collation_connection
に使用する特定の照合を指定するには、COLLATE
句を追加します:SET NAMES 'charset_name' COLLATE 'collation_name'
-
SET CHARACTER SET '
'charset_name
SET CHARACTER SET
はSET NAMES
と似ていますが、character_set_connection
およびcollation_connection
をcharacter_set_database
およびcollation_database
に設定します (前述のように、デフォルトデータベースの文字セットおよび照合順序を示します)。SET CHARACTER SET
ステートメントは次の 3 つのステートメントと同等です。charset_name
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
でこれらを使用しようとすると、エラーが発生します。 許可されていないクライアント文字セットを参照してください。
例: column1
が CHAR(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.0utf8mb4
照合 (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;