MySQL8系でutf8mb4なテーブルに4バイトのUnicode文字🍣🍺があっても、JetBrains系IDEやDataGripにて確認できるようにする

MySQL8系でutf8mb4なテーブルに4バイトのUnicode文字(例: 🍣🍺)があるとき、JetBrains系IDEやDataGripで確認すると ?? のように表示されていました。

 
一方、mysqlコマンドでは 🍣🍺 と正しく表示されていました。

そこで、JetBrains系IDEでも表示できるよう設定を変更したときのメモを残します。

 
目次

 

環境

  • MySQL 8.0.33
  • DataGrip 2023.1.2
    • 今回はDataGripを使いますが、JetBrains系IDEのデータベースツールでも同じだと思います
  • MySQL Connector/J 8.0.25
    • DataGrip内部で使っているMySQLドライバー

 

再現

Docker Composeを使って再現してみます。

 

Docker Composeの準備

compose.ymlの作成

MySQL 8.0.33のイメージを使って環境を用意します。

また、文字コードの設定をするために my.cnf を、テーブルの初期値を投入するために scripts ディレクトリを、それぞれvolumesに指定しておきます。

services:
  db:
    image: mysql:8.0.33
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test_db
      MYSQL_USER: foo
      MYSQL_PASSWORD: bar
    ports:
      - "13306:3306"
    volumes:
      - mysql-vol:/var/lib/mysql
      - ./my.cnf:/etc/mysql/conf.d/my.cnf
      - ./scripts:/docker-entrypoint-initdb.d

volumes:
  mysql-vol:

 

my.cnfの作成

今回はすべて utf8mb4 にしておきます。

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_bin

[mysql]
default-character-set=utf8mb4

[client]
default-character-set=utf8mb4

 

scripts/init.sqlの作成

ホストの scripts ディレクトリに init.sql ファイルを用意します。

ここではテーブルの作成と、 🍣🍺 という値を持つ初期データの投入を行います。

CREATE TABLE articles (
  id   INT PRIMARY KEY AUTO_INCREMENT,
  memo VARCHAR(100)
) ENGINE=InnoDB;

INSERT INTO articles (memo) VALUES ('🍣🍺');

 

Docker Composeの起動

$ docker compose up -d
...
 ⠿ Network mysql_utf8mb4_default     Created
 ⠿ Volume "mysql_utf8mb4_mysql-vol"  Created
 ⠿ Container mysql                   Started

 

動作確認

ログの確認

起動したら動作確認をします。

まずは、コンテナ名 mysql のログを確認します。初期データの投入は成功したようです。

$ docker logs mysql
...
2023-07-12 13:19:00+00:00 [Note] [Entrypoint]: Creating database test_db
2023-07-12 13:19:00+00:00 [Note] [Entrypoint]: Creating user foo
2023-07-12 13:19:00+00:00 [Note] [Entrypoint]: Giving user foo access to schema test_db

2023-07-12 13:19:00+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sql
...

 

テーブルの確認

続いて、 mysql コマンドを使ってテーブルの中身を確認していきます。

docker compose exec <service名> bash を使ってコンテナに入り、mysqlコマンドを使用します。

$ docker compose exec db bash

bash-4.4# mysql -ufoo -pbar -hlocalhost

 
character_set_*** 関係を確認すると、 utf8mb4 になっていました。

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> use test_db

mysql> show tables;
+-------------------+
| Tables_in_test_db |
+-------------------+
| articles          |
+-------------------+
1 row in set (0.00 sec)

mysql> select * from articles;
+----+----------+
| id | memo     |
+----+----------+
|  1 | 🍣🍺         |
+----+----------+
1 row in set (0.00 sec)

 

DataGripでの確認

DataGripを開き、DataSourceとして MySQL を選択します。

続いて、 compose.yml などに従い、設定を行います。

 
準備ができたので、DataGripにて動作確認をします。

Query Consoleを開き、 show variables like '%char%'; を実行します。

すると、先ほどの mysql コマンドの結果とは異なり、 character_set_resultsutf8mb3 になっていました。

 
続いて、テーブルを開いて中身を確認すると、冒頭の画像のように 🍣🍺 が ?? に差し替わっていました。

 
これで、 mysql コマンドでは 🍣🍺 が表示されていたのにも関わらず、DataGripでは正しく表示されないことが再現できました。

 

対応

設定変更

DataGripを使い続けたいので方法を調べたところ、YouTrackに情報がありました。
Emojis are not displayed correctly - question marks ?? displayed instead. : DBE-17035

 
内容を見ると、 characterSetResultsnull にすれば良さそうです。

 
そこで、DataGripのpropertyにある Advanced タブを開き、 characterSetResultsutf8 から null に変更します。

 

動作確認

改めて、DataGripで動作確認を行います。

Query Consoleを開き、 show variables like '%char%'; を実行すると、 character_set_results が空欄になっていました。

 
続いてテーブルを開いてみると、 🍣🍺 が表示されました。良さそうです。

 

ソースコード

再現するためのコードをGithubに上げました。
https://github.com/thinkAmi-sandbox/mysql_utf8mb4-example

 
プルリクはこちらです。
https://github.com/thinkAmi-sandbox/mysql_utf8mb4-example/pull/1