mita2 database life

主にMySQLに関するメモです

MySQL collation_server を変えたつもりが変わってなかった話

character_set_server と collation_server

これらのパラメータは、データベースを作成する際に、何もキャラクタセットや照合順序を明示的に指定しなかった場合に、採用されるキャラクタセット・照合順序です (ちなみにテーブル作成時に何も指定しなかった場合は、テーブルはスキーマのキャラクタセットや照合順序を引き継く)。

mysql> show global variables like 'character_set_server';
+----------------------+---------+
| Variable_name        | Value   |
+----------------------+---------+
| character_set_server | utf8mb4 |
+----------------------+---------+
1 row in set (0.00 sec)

mysql> show global variables like 'collation_server';
+------------------+--------------------+
| Variable_name    | Value              |
+------------------+--------------------+
| collation_server | utf8mb4_general_ci |
+------------------+--------------------+
1 row in set (0.01 sec)

-- キャラクタセット・照合順序を指定しない
mysql> create database d1;
Query OK, 1 row affected (0.01 sec)


-- character_set_server と collation_server の値が引き継がれてる
mysql> show create database d1 \G
*************************** 1. row ***************************
       Database: d1
Create Database: CREATE DATABASE `d1` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */
1 row in set (0.00 sec)

collation_server を変えたつもりが変わってなかった...

character_set_servercollation_server の順番でSET GLOBAL 指定すれば問題ありませんが、

mysql> SET GLOBAL character_set_server=utf8mb4, collation_server=utf8mb4_bin;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GLOBAL VARIABLES LIKE 'collation_server';
+------------------+-------------+
| Variable_name    | Value       |
+------------------+-------------+
| collation_server | utf8mb4_bin |
+------------------+-------------+
1 row in set (0.00 sec)

逆の順番だと、collation_server の変更がなかったことになってしまいます。

mysql> SET GLOBAL collation_server=utf8mb4_bin, character_set_server=utf8mb4;
Query OK, 0 rows affected (0.00 sec)

-- utf8mb4_bin になってない
mysql> SHOW GLOBAL VARIABLES LIKE 'collation_server';
+------------------+--------------------+
| Variable_name    | Value              |
+------------------+--------------------+
| collation_server | utf8mb4_0900_ai_ci |
+------------------+--------------------+
1 row in set (0.00 sec)

character_set_server を変えると、collation_server が連動して、各キャラクタセットのデフォルトの照合順序にリセットされるみたい。 キャラクタセットと照合順序は使える組み合わせが決まっているため、collation_servercharacter_set_server の値に連動する仕様なんでしょう。

character_set_server を 今と同じ値に SET GLOBAL しても何も起きないよね〜」と思って雑なスクリプトを書いてたりすると、意図せず character_set_server がリセットされる。

mysql> SHOW GLOBAL VARIABLES LIKE 'collation_server';
+------------------+-------------+
| Variable_name    | Value       |
+------------------+-------------+
| collation_server | utf8mb4_bin |
+------------------+-------------+
1 row in set (0.00 sec)

mysql> SET GLOBAL character_set_server=@@character_set_server;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GLOBAL VARIABLES LIKE 'collation_server';
+------------------+--------------------+
| Variable_name    | Value              |
+------------------+--------------------+
| collation_server | utf8mb4_0900_ai_ci |
+------------------+--------------------+
1 row in set (0.00 sec)

まとめ

  • character_set_server を変えると、collation_server が連動して、各キャラクタセットのデフォルトの照合順序にリセットされるよ!