日本語版Wikipedia SQLダンプデータをインポートすると日本語が変な見た目になる

過去にも、Wikipediaダンプデータに関する以下の記事を出しました。

https://qiita.com/tekunikaruza_jp/items/93d3267a444acef470d9

前回は、英語版Wikipediaを例で紹介しましたが、今回は日本語版に関すること。

# 事象

環境は、
MySQL: 8.0.26
OS: Ubuntu 20 及び Windows 10 で検証 (Dockerでも検証)

[https://dumps.wikimedia.org/jawiki/](https://dumps.wikimedia.org/jawiki/)から、ページ一覧やカテゴリ一覧などのダンプデータを、SQL形式で取得することができます。これらはMySQLのダンプデータのようですので、活用したいときは、自身のMySQLデータベースにインポート(リストア)します。

ただ、単純にインポートし、テーブルを`SELECT`すると、文字列型のカラムが下記のように表示されました。(categoryテーブルを例に。)

```
mysql> SELECT * FROM category LIMIT 10;
+--------+----------------------------------------------------------------------------------------+-----------+-------------+-----------+
| cat_id | cat_title                                                                              | cat_pages | cat_subcats | cat_files |
+--------+----------------------------------------------------------------------------------------+-----------+-------------+-----------+
|      1 | 0xE698A0E794BBE996A2E980A3E381AEE382B9E382BFE38396E9A085E79BAE                         |     12056 |           3 |         0 |
|      2 | 0xE6B4BBE58B95E5819CE6ADA2E4B8ADE381AEE382A6E382A3E382ADE3839AE38387E382A3E382A2E383B3 |       445 |           0 |         0 |
|      3 | 0xE8A1A8E8A898                                                                         |        33 |          11 |         0 |
|      4 | 0xE794BBE5838FE68F90E4BE9BE4BE9DE9A0BC                                                 |       137 |           2 |         3 |
|      5 | 0xE8BB8DE4BA8BE888AAE7A9BAE382B9E382BFE38396                                           |       693 |           0 |         0 |
|      6 | 0xE58DB3E69982E5898AE999A4                                                             |         9 |           5 |         0 |
|      7 | 0xE694BFE6B2BBE996A2E980A3E381AEE382B9E382BFE38396E9A085E79BAE                         |      3506 |           4 |         0 |
|      8 | 0xE58886E589B2E68F90E6A188                                                             |        38 |           1 |         0 |
|      9 | 0xE69B96E698A7E38195E59B9EE981BF                                                       |     53814 |          26 |         0 |
|     10 | 0xE382A4E382AEE383AAE382B9E381AEE698A0E794BBE4BD9CE59381                               |        18 |           5 |         0 |
+--------+----------------------------------------------------------------------------------------+-----------+-------------+-----------+
10 rows in set (0.00 sec)
```

`cat_title`列の文字列がバイナリになってますね。

HeidiSQLで、バイナリデータをテキストデータとして表示させると、こんな見た目になりました。文字化けしています。

![HeidiSQL](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84550/2304baa9-9843-e5bc-3726-28a51259058f.png)

# 原因

ダンプファイルのテーブル定義文を見てみると、文字列のカラムのデータ型が、`varbinary`になっています。

```sql:categoryのテーブル定義
CREATE TABLE `category` (
  `cat_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `cat_title` varbinary(255) NOT NULL DEFAULT '', -- 例えばこのカラム！！！
  `cat_pages` int(11) NOT NULL DEFAULT 0,
  `cat_subcats` int(11) NOT NULL DEFAULT 0,
  `cat_files` int(11) NOT NULL DEFAULT 0,
  PRIMARY KEY (`cat_id`),
  UNIQUE KEY `cat_title` (`cat_title`),
  KEY `cat_pages` (`cat_pages`)
) ENGINE=InnoDB AUTO_INCREMENT=8297323 DEFAULT CHARSET=binary ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
```

`VARBINARY`は、文字列をバイナリデータとして格納する型ですが、何らかの原因で、正しくデコードできていない？きちんとした原因は分かりません。

MySQLの文字コードに関する設定もいろいろ見直してみましたが、解決できませんでした。

```:MySQL、データベース、テーブルの各文字コード設定を確認している様子
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 create database jawiki;
+----------+-----------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database                                                                                                             |
+----------+-----------------------------------------------------------------------------------------------------------------------------+
| jawiki   | CREATE DATABASE `jawiki` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin */ /*!80016 DEFAULT ENCRYPTION='N' */  |
+----------+-----------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> show create table category;
+----------+------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                             |
+----------+------------------------------------------------------------------------------------------+
| category | CREATE TABLE `category` (
  `cat_id` int unsigned NOT NULL AUTO_INCREMENT,
  `cat_title` varbinary(255) NOT NULL DEFAULT '',
  `cat_pages` int NOT NULL DEFAULT '0',
  `cat_subcats` int NOT NULL DEFAULT '0',
  `cat_files` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`cat_id`),
  UNIQUE KEY `cat_title` (`cat_title`),
  KEY `cat_pages` (`cat_pages`)
) ENGINE=InnoDB AUTO_INCREMENT=8297323 DEFAULT CHARSET=binary ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8 |
+----------+-----------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
```

# 無理やり解決方法

SQLファイル内のテーブル定義において、`varbinary`型になっているカラムを`varchar`型に変えてやります。加えて、`BINARY`属性を付与します。
さらに、テーブルのCHARSETを`utf8mb4`に変更します。

例えば、`category`テーブルの場合、下記のように書き換えます。

![diff](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84550/22cc9a50-7b91-f0cf-88e6-640a6c760069.png)

```sql:書き換え後
CREATE TABLE `category` (
  `cat_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `cat_title` varchar(255) BINARY NOT NULL DEFAULT '',
  `cat_pages` int(11) NOT NULL DEFAULT 0,
  `cat_subcats` int(11) NOT NULL DEFAULT 0,
  `cat_files` int(11) NOT NULL DEFAULT 0,
  PRIMARY KEY (`cat_id`),
  UNIQUE KEY `cat_title` (`cat_title`),
  KEY `cat_pages` (`cat_pages`)
) ENGINE=InnoDB AUTO_INCREMENT=8297323 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
```

これでSQLファイルをインポートすると、一応、文字列を正しく取り扱うことができるようになります。

```
mysql> SELECT * FROM category LIMIT 10;
+--------+--------------------------------------------+-----------+-------------+-----------+
| cat_id | cat_title                                  | cat_pages | cat_subcats | cat_files |
+--------+--------------------------------------------+-----------+-------------+-----------+
|      1 | 映画関連のスタブ項目                       |     12056 |           3 |         0 |
|      2 | 活動停止中のウィキペディアン               |       445 |           0 |         0 |
|      3 | 表記                                       |        33 |          11 |         0 |
|      4 | 画像提供依頼                               |       137 |           2 |         3 |
|      5 | 軍事航空スタブ                             |       693 |           0 |         0 |
|      6 | 即時削除                                   |         9 |           5 |         0 |
|      7 | 政治関連のスタブ項目                       |      3506 |           4 |         0 |
|      8 | 分割提案                                   |        38 |           1 |         0 |
|      9 | 曖昧さ回避                                 |     53814 |          26 |         0 |
|     10 | イギリスの映画作品                         |        18 |           5 |         0 |
+--------+--------------------------------------------+-----------+-------------+-----------+
10 rows in set (0.00 sec)
```

![HeidiSQL](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84550/f84825ba-db8e-c7ba-2c41-4243343e30d3.png)

もともとのダンプデータでのデータ型が`varbinary`型である理由が分からないため、根本的解決でない点、ご了承ください。

ご存じの方はお教えいただけますと幸いです。