MySQL・phpMyAdmin の文字化けを直す

MySQL や phpMyAdmin で日本語が ???? になったり、山田 のような記号に化けたりしていませんか?原因は、テーブル・接続・ファイルの文字コードが食い違っていることです。化けたエクスポートはブラウザー内で修正でき、MySQL を utf8mb4 に統一すれば再発を防げます。

テキストと次のファイルに対応:

  • CSV
  • TXT
  • JSON
  • XML
  • SRT
  • VTT
  • TSV
  • MD
  • HTML
  • SQL
  • LOG

Excel の CSV、データベースのダンプ、字幕、Web サイトのコードなど。

修正する

  1. ファイルをドロップ、またはテキストを貼り付け
  2. 自動で修正
  3. コピーまたはダウンロード
またはファイルをここにドラッグ
  • アップロードなし。 ファイルはブラウザー内で修正され、端末の外に出ることはありません。

  • EU 内のサーバー。 Mojibuster は フィンランド(EU)のサーバーで運用しており、EU 一般データ保護規則(GDPR)が適用されます。 GDPR の条文(EUR-Lex、英語)

MySQL で文字コードが関わる 3 か所

  • 列・テーブル: データを保存する文字コードです。utf8mb4 のほか、古いシステムでは latin1、sjis、cp932、ujis(EUC-JP)も使われています。
  • 接続: アプリと MySQL がやり取りする文字コードです。SET NAMES utf8mb4 や接続設定で指定します。
  • ファイル: インポートやエクスポートで使う文字コードです。phpMyAdmin ではインポート・エクスポート画面でファイルの文字セットを選べます。コマンドラインで結果が化ける場合は PowerShell の文字化け も参考になります。

3 か所のどれかが食い違うと文字が化けます。症状は大きく 2 種類に分かれ、直せるかどうかも違います。

日本語が ???? になる場合

列や接続の文字コードが日本語を表せないと、MySQL は文字を ? に置き換えて保存します。よくあるのは、列や接続が latin1 のままになっているケースです。接続が cp932 や sjis の場合も、CP932 にない絵文字などは ? になります。

utf8(実体は 3 バイトまでの utf8mb3)の列に絵文字や 𠮷 のような 4 バイトの文字を入れると、Incorrect string value エラーになるか、設定によっては文字が欠けます。いったん ? として保存された文字は情報が失われているため、Mojibuster でも元に戻せません。

山田 のように化ける場合

UTF-8 の文章が latin1 の接続で latin1 の列に書き込まれると、アプリでは正しく見えても、phpMyAdmin やエクスポートでは 山田 のように表示されます。この場合はバイトが残っているので修正できます。

phpMyAdmin から書き出した CSV の 1 行

文字化け

"1","山田太郎","大阪府","営業部"

修正後

"1","山田太郎","大阪府","営業部"

文字コードを確認する

  • SHOW VARIABLES LIKE 'character_set%'; で、サーバーと接続の設定がわかります。
  • SHOW CREATE TABLE customers; で、テーブルと列の文字コードがわかります。
  • SELECT name, HEX(name) FROM customers LIMIT 5; で実際のバイトを確認できます。utf8mb4 の列で E5B1B1 なら正しい「山」、C3A5C2B1C2B1 ならすでに化けた å±± です。

エクスポートやダンプを修正する

  1. phpMyAdmin でテーブルを SQL または CSV で書き出すか、mysqldump --default-character-set=utf8mb4 を使います。
  2. 上の枠にファイルをドロップします。Mojibuster は化けた箇所だけを直し、正しい文字には手を加えません。
  3. 変更箇所 で修正内容を確認し、ファイルをダウンロードします。
  4. utf8mb4 のテーブルに取り込み、インポート画面の文字セットは utf-8 を選びます。
  5. 本番のテーブルを置き換える前に、まずコピーで試してください。

ダンプはブラウザーの外に出ないので、顧客データを含むファイルでも安心して扱えます。書き出した CSV を Excel で開くと化ける場合は、Excel の CSV 文字化け を参照してください。

原因を直す

  • 新しいテーブルは DEFAULT CHARSET=utf8mb4 で作ります。
  • アプリの接続も utf8mb4 にします。PHP なら PDO の DSN に charset=utf8mb4 を付けます。
  • latin1 の列に UTF-8 のバイトが入っている場合、CONVERT TO で直接変換してはいけません。もう一度エンコードされ、二重に化けます。安全なのはバイナリ型を経由する方法です。まず MODIFY name VARBINARY(255)、次に MODIFY name VARCHAR(255) CHARACTER SET utf8mb4 を実行します。
  • sjis や ujis の列に日本語が正しく入っている場合は、ALTER TABLE customers CONVERT TO CHARACTER SET utf8mb4 でそのまま変換できます。

よくある質問

アプリでは正しく表示されるのに、phpMyAdmin では化けるのはなぜですか?

アプリと MySQL が同じ間違いを 2 回しているからです。アプリは UTF-8 を latin1 の接続で書き込み、同じ接続で読み戻すので正しく見えます。phpMyAdmin は正しい接続で読むため、実際に保存されている化けた状態が見えます。

照合順序(collation)は何を選べばよいですか?

まず文字コードを utf8mb4 にすることが大切です。照合順序によっては日本語の比較に癖があり、utf8mb4_general_ci などでは 🍣 と 🍺 が同じ文字として扱われる「寿司ビール問題」、MySQL 8 の標準 utf8mb4_0900_ai_ci では「ハ」と「パ」が区別されない問題が知られています。区別が必要な列には utf8mb4_ja_0900_as_cs や utf8mb4_bin を検討してください。

MariaDB でも同じですか?

はい。文字コードの扱いは MySQL と同じで、上のコマンドもそのまま使えます。

どのくらいの大きさのダンプまで扱えますか?

1 ファイル 100 MB までです。大きなデータベースはテーブルごとに書き出してください。

関連ガイド