MySQL8.0の文字コード再確認

default_collation_for_utf8mb4

以前に文字コードに関して少しまとめましたが、サーバー初期設定時のMySQL8.0のperformance_schemaはutf8mb4_0900_ai_ciになっていて、default_collation_for_utf8mb4の設定にてutf8mb4のdefault Collationをutf8mb4_general_ciにした場合に一部のSYSスキーマの参照でエラーになったので再確認。

結果としては、statement_analysisを実行する時にVIEWの中で実行しているsys.format_statementの処理が,COLLATIONの違いでエラーになってしまっていたようでした。

DEFAULT COLLATIONに関して

default_collation_for_utf8mb4を設定している環境では、DDL実行時にCOLLATIONの設定を指定しなくても、default_collation_for_utf8mb4で設定したCollationが設定された状態でテーブルを作成する事が出来る。但し、default_collation_for_utf8mb4はdeprecateのお知らせが出ているので使い続ける事は難しい??であれば、DDLを利用する時には必ずCOLLATE句を付けて実行すれば良いが、もしREAD-ONLYでパラメータが次のメジャーバージョンでも残るのであれば、使いたい場合はPERSISTで設定しておけば良いのかもしれない。

Deprecated Notice (SET PERSISTで起動時のみに読み込むREAD-ONLYの値であれば良いのかな?念の為に確認しておく。)

Depricate Notification

default_collation_for_utf8mb4=utf8mb4_general_ciの場合の挙動

テーブル: T_general_ci(COLLATE指定) T_Default_Ci (COLLATE指定無し)

mysql>  show create database COLLATION_DB\G
*************************** 1. row ***************************
       Database: COLLATION_DB
Create Database: CREATE DATABASE `COLLATION_DB` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */
1 row in set (0.00 sec)

mysql> CREATE TABLE `T_general_ci` (
    -> `ID` int NOT NULL AUTO_INCREMENT,
    -> `NOTE` varchar(100) NOT NULL DEFAULT '',
    -> PRIMARY KEY (`ID`)
    -> ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
Query OK, 0 rows affected (0.06 sec)

mysql> CREATE TABLE `T_Default_Ci` (
    -> `ID` int NOT NULL AUTO_INCREMENT,
    -> `NOTE` varchar(100) NOT NULL DEFAULT '',
    -> PRIMARY KEY (`ID`)
    -> ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; /*** COLLATE指定無し ***/
Query OK, 0 rows affected (0.04 sec)

mysql> show create table `T_general_ci`\G
*************************** 1. row ***************************
       Table: T_general_ci
Create Table: CREATE TABLE `T_general_ci` (
  `ID` int NOT NULL AUTO_INCREMENT,
  `NOTE` varchar(100) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
1 row in set (0.00 sec)

mysql> show create table `T_Default_Ci` \G
*************************** 1. row ***************************
       Table: T_Default_Ci
Create Table: CREATE TABLE `T_Default_Ci` (
  `ID` int NOT NULL AUTO_INCREMENT,
  `NOTE` varchar(100) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci  /*** Default COLLATEになる ***/
1 row in set (0.00 sec)

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

mysql> show variables like '%col%';
+---------------------------------+------------------------+
| Variable_name                   | Value                  |
+---------------------------------+------------------------+
| collation_connection            | utf8mb4_0900_ai_ci     |
| collation_database              | utf8mb4_general_ci     |
| collation_server                | utf8mb4_general_ci     |
| default_collation_for_utf8mb4   | utf8mb4_general_ci     |
| protocol_compression_algorithms | zlib,zstd,uncompressed |
| protocol_version                | 10                     |
| replica_compressed_protocol     | OFF                    |
| slave_compressed_protocol       | OFF                    |
+---------------------------------+------------------------+
8 rows in set (0.00 sec)

mysql>

default_collation_for_utf8mb4=を指定しない場合

MySQL8.0のutf8mb4のdefault Collationを利用しいて、default_collation_for_utf8mb4でcollationを指定しない場合は、テーブルのcollationはutf8mb4_0900_ai_ciになる。Collationの違いによる文字の判別に関してはMitaniさんのブログにて丁寧に説明されているので参考にされると良いと思います。

Default Collation

default_collation_for_utf8mb4を変更せずにDDLを実行した場合。(utf8mb4_0900_ai_ci)

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

mysql> show variables like '%col%';
+---------------------------------+------------------------+
| Variable_name                   | Value                  |
+---------------------------------+------------------------+
| collation_connection            | utf8mb4_0900_ai_ci     |
| collation_database              | utf8mb4_general_ci     |
| collation_server                | utf8mb4_general_ci     |
| default_collation_for_utf8mb4   | utf8mb4_0900_ai_ci     |
| protocol_compression_algorithms | zlib,zstd,uncompressed |
| protocol_version                | 10                     |
| replica_compressed_protocol     | OFF                    |
| slave_compressed_protocol       | OFF                    |
+---------------------------------+------------------------+
8 rows in set (0.00 sec)

mysql> CREATE TABLE `T_Default_0900_ai_ci` (
    -> `ID` int NOT NULL AUTO_INCREMENT,
    -> `NOTE` varchar(100) NOT NULL DEFAULT '',
    -> PRIMARY KEY (`ID`)
    -> ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
Query OK, 0 rows affected (0.05 sec)

mysql> show create table `T_Default_0900_ai_ci`\G
*************************** 1. row ***************************
       Table: T_Default_0900_ai_ci
Create Table: CREATE TABLE `T_Default_0900_ai_ci` (
  `ID` int NOT NULL AUTO_INCREMENT,
  `NOTE` varchar(100) NOT NULL DEFAULT '',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*** Default COLLATEになる ***/
1 row in set (0.01 sec)

mysql>

上記の様に、オブジェクトのCOLLATIONがどうなるかを把握すると同時に、オプションファイルには”character-set-server = utf8mb4″, “collation_server = utf8mb4_general_ci”等の値を設定して、データベースオブジェクトを作成する時にCOLLATIONをしっかり指定する癖を付ければ問題は無さそうだけど、default_collation_for_utf8mb4の値をutf8mb4_general_ciに変更した場合にSYSスキーマで実行している処理にてCollationのミスマッチが発生してエラーになってしまったので確認。

statement_analysis実行時のIllegal mix of collationsエラーの発生について

実行環境

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

mysql> show variables like '%col%';
+---------------------------------+------------------------+
| Variable_name                   | Value                  |
+---------------------------------+------------------------+
| collation_connection            | utf8mb4_0900_ai_ci     |
| collation_database              | utf8mb4_general_ci     |
| collation_server                | utf8mb4_general_ci     |
| default_collation_for_utf8mb4   | utf8mb4_general_ci     |
| protocol_compression_algorithms | zlib,zstd,uncompressed |
| protocol_version                | 10                     |
| replica_compressed_protocol     | OFF                    |
| slave_compressed_protocol       | OFF                    |
+---------------------------------+------------------------+
8 rows in set (0.00 sec)

mysql> select * from version;
+-------------+---------------+
| sys_version | mysql_version |
+-------------+---------------+
| 2.1.2       | 8.0.31        |
+-------------+---------------+
1 row in set (0.00 sec)

mysql> show create view version\G
*************************** 1. row ***************************
                View: version
         Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`mysql.sys`@`localhost` SQL SECURITY INVOKER VIEW `version` (`sys_version`,`mysql_version`) AS select '2.1.2' AS `sys_version`,version() AS `mysql_version`
character_set_client: utf8mb4
collation_connection: utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql> select * from statement_analysis;
ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation '='
mysql> show create view statement_analysis\G
*************************** 1. row ***************************
                View: statement_analysis
         Create View: CREATE ALGORITHM=MERGE DEFINER=`mysql.sys`@`localhost` SQL SECURITY INVOKER VIEW `statement_analysis` (`query`,`db`,`full_scan`,`exec_count`,`err_count`,`warn_count`,`total_latency`,`max_latency`,`avg_latency`,`lock_latency`,`cpu_latency`,`rows_sent`,`rows_sent_avg`,`rows_examined`,`rows_examined_avg`,`rows_affected`,`rows_affected_avg`,`tmp_tables`,`tmp_disk_tables`,`rows_sorted`,`sort_merge_passes`,`max_controlled_memory`,`max_total_memory`,`digest`,`first_seen`,`last_seen`) AS select `sys`.`format_statement`(`performance_schema`.`events_statements_summary_by_digest`.`DIGEST_TEXT`) AS `query`,`performance_schema`.`events_statements_summary_by_digest`.`SCHEMA_NAME` AS `db`,if(((`performance_schema`.`events_statements_summary_by_digest`.`SUM_NO_GOOD_INDEX_USED` > 0) or (`performance_schema`.`events_statements_summary_by_digest`.`SUM_NO_INDEX_USED` > 0)),'*','') AS `full_scan`,`performance_schema`.`events_statements_summary_by_digest`.`COUNT_STAR` AS `exec_count`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_ERRORS` AS `err_count`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_WARNINGS` AS `warn_count`,format_pico_time(`performance_schema`.`events_statements_summary_by_digest`.`SUM_TIMER_WAIT`) AS `total_latency`,format_pico_time(`performance_schema`.`events_statements_summary_by_digest`.`MAX_TIMER_WAIT`) AS `max_latency`,format_pico_time(`performance_schema`.`events_statements_summary_by_digest`.`AVG_TIMER_WAIT`) AS `avg_latency`,format_pico_time(`performance_schema`.`events_statements_summary_by_digest`.`SUM_LOCK_TIME`) AS `lock_latency`,format_pico_time(`performance_schema`.`events_statements_summary_by_digest`.`SUM_CPU_TIME`) AS `cpu_latency`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_ROWS_SENT` AS `rows_sent`,round(ifnull((`performance_schema`.`events_statements_summary_by_digest`.`SUM_ROWS_SENT` / nullif(`performance_schema`.`events_statements_summary_by_digest`.`COUNT_STAR`,0)),0),0) AS `rows_sent_avg`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_ROWS_EXAMINED` AS `rows_examined`,round(ifnull((`performance_schema`.`events_statements_summary_by_digest`.`SUM_ROWS_EXAMINED` / nullif(`performance_schema`.`events_statements_summary_by_digest`.`COUNT_STAR`,0)),0),0) AS `rows_examined_avg`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_ROWS_AFFECTED` AS `rows_affected`,round(ifnull((`performance_schema`.`events_statements_summary_by_digest`.`SUM_ROWS_AFFECTED` / nullif(`performance_schema`.`events_statements_summary_by_digest`.`COUNT_STAR`,0)),0),0) AS `rows_affected_avg`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_CREATED_TMP_TABLES` AS `tmp_tables`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_CREATED_TMP_DISK_TABLES` AS `tmp_disk_tables`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_SORT_ROWS` AS `rows_sorted`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_SORT_MERGE_PASSES` AS `sort_merge_passes`,format_bytes(`performance_schema`.`events_statements_summary_by_digest`.`MAX_CONTROLLED_MEMORY`) AS `max_controlled_memory`,format_bytes(`performance_schema`.`events_statements_summary_by_digest`.`MAX_TOTAL_MEMORY`) AS `max_total_memory`,`performance_schema`.`events_statements_summary_by_digest`.`DIGEST` AS `digest`,`performance_schema`.`events_statements_summary_by_digest`.`FIRST_SEEN` AS `first_seen`,`performance_schema`.`events_statements_summary_by_digest`.`LAST_SEEN` AS `last_seen` from `performance_schema`.`events_statements_summary_by_digest` order by `performance_schema`.`events_statements_summary_by_digest`.`SUM_TIMER_WAIT` desc
character_set_client: utf8mb4
collation_connection: utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql>

performance_schema.events_statements_summary_by_digestを直接参照してもエラーにはならないのでもし確認したい場合は直接テーブルを参照すれば良いが、VIEW実行時にエラーになっていたのは以下の箇所(format_statement)の様でした。statement_analysisを実行したときに、DIGEST_TEXTの中身を成型してくれるFunctionの様です。

sys.format_statement(performance_schema.events_statements_summary_by_digest.DIGEST_TEXT) AS query

ERROR (mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT))

IMPLICIT ERROR

ダブルチェック:Functionのcollation_connectionを変更

VIEWの中からネストしている場合だけダメなのかな?と思い、念の為に再確認してみたがやはりダメでした。

format_statementのCOLLATIONを変更してみた:やはり参照しているテーブル自体がutf8mb4_0900_ai_ciなのでNG

format_statementをutf8mb4_generic_ciで作り直してみた

結果

mysql> select * from statement_analysis limit 1\G
ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation '='
mysql>

default_collation_for_utf8mb4をutf8mb4_general_ciにすると,全てのVIEWでは無いが上記の様にSYSスキーマでの参照が変換エラーになるViewがある。utf8mb4_0900_ai_ciだと変換がエラーにならない。変換エラーにならない組み合わせで処理するか?、同時に将来的にどのcollationを選択するのが良いか判断する必要もある。分かりやすい様にDefaultのcollationを使いつつ、運用しているサービスの必要性に応じて、オブジェクト作成時はテーブルや列単位で適宜適切なcollationを指定するのが最適な運用の解なのかもしれないとも思う。基本的にはサーバー、クライアント含めて全体で揃えておくのがベストプラクティスではあるので、MySQL8.0にアップグレードする場合は事前に挙動をきちんと確認して、自社のサービスにとって最適なcollationを選択しておく必要がある事に変わりはない。

ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation ‘=’

mysql> set global default_collation_for_utf8mb4 =utf8mb4_0900_ai_ci;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> exit
Bye
PC:~/github/rdbms-docker/mysql$ mysql -h 127.0.0.1 -P13306 -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 8.0.31 MySQL Community Server - GPL

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use sys
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show variables like '%col%';
+---------------------------------+------------------------+
| Variable_name                   | Value                  |
+---------------------------------+------------------------+
| collation_connection            | utf8mb4_0900_ai_ci     |
| collation_database              | utf8mb4_general_ci     | /*** CREATE時に指定 ***/
| collation_server                | utf8mb4_general_ci     |  /*** サービス仕様に合わせる。my.cnf ***/
| default_collation_for_utf8mb4   | utf8mb4_0900_ai_ci     | /*** Object作成時に指定して対応 ***/
| protocol_compression_algorithms | zlib,zstd,uncompressed |
| protocol_version                | 10                     |
| replica_compressed_protocol     | OFF                    |
| slave_compressed_protocol       | OFF                    |
+---------------------------------+------------------------+
8 rows in set (0.00 sec)

mysql> select * from statement_analysis limit 1\G
*************************** 1. row ***************************
                query: CREATE TABLE `T_general_ci` (  ... COLLATE = `utf8mb4_general_ci`
                   db: COLLATION_DB
            full_scan:
           exec_count: 1
            err_count: 0
           warn_count: 0
        total_latency: 51.34 ms
          max_latency: 51.34 ms
          avg_latency: 51.34 ms
         lock_latency: 24.00 us
          cpu_latency:   0 ps
            rows_sent: 0
        rows_sent_avg: 0
        rows_examined: 0
    rows_examined_avg: 0
        rows_affected: 0
    rows_affected_avg: 0
           tmp_tables: 0
      tmp_disk_tables: 0
          rows_sorted: 0
    sort_merge_passes: 0
max_controlled_memory: 1.02 MiB
     max_total_memory: 5.94 MiB
               digest: 60e74ac690f79684925c8f639b2bad0a6be6a8d7ad6053465fba64c1afbd21f2
           first_seen: 2022-11-11 23:02:05.609367
            last_seen: 2022-11-11 23:02:05.609367
1 row in set (0.01 sec)
events_statements_summary_by_digest (utf8mb4_0900_ai_ci)

これまでMySQL5.7でDDL実行時にCOLLATEを指定して無かったDBAも意識しておく必要ある。utf8mb4_0900_ai_ciの仕様が全く問題にならない場合はdefaultのまま使えば良い。

メモ: Performance_Schema内のテーブルCOLLATION

mysql> show create table `performance_schema`.`events_statements_summary_by_digest`\G
*************************** 1. row ***************************
       Table: events_statements_summary_by_digest
Create Table: CREATE TABLE `events_statements_summary_by_digest` (
  `SCHEMA_NAME` varchar(64) DEFAULT NULL,
  `DIGEST` varchar(64) DEFAULT NULL,
  `DIGEST_TEXT` longtext,
  `COUNT_STAR` bigint unsigned NOT NULL,
  `SUM_TIMER_WAIT` bigint unsigned NOT NULL,
  `MIN_TIMER_WAIT` bigint unsigned NOT NULL,
  `AVG_TIMER_WAIT` bigint unsigned NOT NULL,
  `MAX_TIMER_WAIT` bigint unsigned NOT NULL,
  `SUM_LOCK_TIME` bigint unsigned NOT NULL,
  `SUM_ERRORS` bigint unsigned NOT NULL,
  `SUM_WARNINGS` bigint unsigned NOT NULL,
  `SUM_ROWS_AFFECTED` bigint unsigned NOT NULL,
  `SUM_ROWS_SENT` bigint unsigned NOT NULL,
  `SUM_ROWS_EXAMINED` bigint unsigned NOT NULL,
  `SUM_CREATED_TMP_DISK_TABLES` bigint unsigned NOT NULL,
  `SUM_CREATED_TMP_TABLES` bigint unsigned NOT NULL,
  `SUM_SELECT_FULL_JOIN` bigint unsigned NOT NULL,
  `SUM_SELECT_FULL_RANGE_JOIN` bigint unsigned NOT NULL,
  `SUM_SELECT_RANGE` bigint unsigned NOT NULL,
  `SUM_SELECT_RANGE_CHECK` bigint unsigned NOT NULL,
  `SUM_SELECT_SCAN` bigint unsigned NOT NULL,
  `SUM_SORT_MERGE_PASSES` bigint unsigned NOT NULL,
  `SUM_SORT_RANGE` bigint unsigned NOT NULL,
  `SUM_SORT_ROWS` bigint unsigned NOT NULL,
  `SUM_SORT_SCAN` bigint unsigned NOT NULL,
  `SUM_NO_INDEX_USED` bigint unsigned NOT NULL,
  `SUM_NO_GOOD_INDEX_USED` bigint unsigned NOT NULL,
  `SUM_CPU_TIME` bigint unsigned NOT NULL,
  `MAX_CONTROLLED_MEMORY` bigint unsigned NOT NULL,
  `MAX_TOTAL_MEMORY` bigint unsigned NOT NULL,
  `COUNT_SECONDARY` bigint unsigned NOT NULL,
  `FIRST_SEEN` timestamp(6) NOT NULL,
  `LAST_SEEN` timestamp(6) NOT NULL,
  `QUANTILE_95` bigint unsigned NOT NULL,
  `QUANTILE_99` bigint unsigned NOT NULL,
  `QUANTILE_999` bigint unsigned NOT NULL,
  `QUERY_SAMPLE_TEXT` longtext,
  `QUERY_SAMPLE_SEEN` timestamp(6) NOT NULL,
  `QUERY_SAMPLE_TIMER_WAIT` bigint unsigned NOT NULL,
  UNIQUE KEY `SCHEMA_NAME` (`SCHEMA_NAME`,`DIGEST`)
) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql>

備考:Performance Schemaなので、都合良く以下の様なコマンドは勿論できません。出来ても困るけど。

ALTER TABLE events_statements_summary_by_digest CONVERT TO CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci';

COLLATIONの違いによる比較処理エラー : (utf8mb4_general_ci & utf8mb4_0900_ai_ci)

こちらは、再びMitaniさんのブログにて検証されている内容が参考になるかと思います。

mysql> SELECT _utf8mb4"比較" COLLATE utf8mb4_general_ci = _utf8mb4"比較" COLLATE utf8mb4_general_ci;
+-------------------------------------------------------------------------------------------+
| _utf8mb4"比較" COLLATE utf8mb4_general_ci = _utf8mb4"比較" COLLATE utf8mb4_general_ci     |
+-------------------------------------------------------------------------------------------+
|                                                                                         1 |
+-------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT _utf8mb4"比較" COLLATE utf8mb4_general_ci = _utf8mb4"比較" COLLATE utf8mb4_0900_ai_ci;
ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_general_ci,EXPLICIT) and (utf8mb4_0900_ai_ci,EXPLICIT) for operation '='
mysql>
COLLATIONの違いによる比較時エラーの確認

default_collation_for_utf8mb4にutf8mb4_general_ciを利用したい場合。collationの違いで参照出来ないシステムテーブルの列がある場合は、その列だけcollationを参照時に変換してあげれば良さそう。パフォーマンス的な事は適宜考慮して確認して下さい。

メモ:コネクションのCOLLATIONを変更

クライアントコネクションを設定してユーザーオブジェクトの設定を合わせた設定

COLLATIONに関する備考

マニュアルにてCOLLATIONの優先順位を見ても、ユーザーオブジェクトに関してはオブジェクトとクライアントのキャラクターセットと同じにしておけば運用で特に問題は無いと理解。また、カラム参照時はカラムが優先される。

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

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

移行参考事例

サイボウズさんでも色々と検証されて、自社の運用にとって最適な選択肢を取られてMySQL8.0に移行された様ですので参考にされのも良いかと思います。

FOOTNOTE:

直近3年はPostgreSQLをメインに仕事をしていて、MySQL8.0は一部の業務のみでしか利用していなかったので、暫くMySQL8.0の多くの仕様変更に追従し切れてませんでした。簡単に追加された機能やDeprecateになった主な機能を見直しているので、まとまったら分かりやすく纏めておきます。まだ編集中ですが参考までに。

https://docs.google.com/spreadsheets/d/1azePTqSRzatS-r2mrUVpTCZje1N6jzT2/edit#gid=2123224682

カテゴリー:

最近のコメント

表示できるコメントはありません。