2026年6月25日
2026年6月25日
WordPressのデータベースをutf8mb4に統一する方法|確認・変換・wp-config.phpの設定
WordPress のデータベースの文字コードは utf8mb4 が標準です。古いサイトでは、テーブルが utf8(新しい MySQL・MariaDB の表示では utf8mb3)や latin1 のまま残っていることがあります。utf8(utf8mb3)は1文字3バイトまでしか保存できず、絵文字や一部の漢字(4バイトの文字)を保存できません。
この記事では、今の文字コードを調べ、utf8mb4 に変換し、変換後に確かめるまでを説明します。WordPress の動作は WordPress のソースコード(wp-includes/class-wpdb.php など)で確認しました(2026年11月時点)。
utf8 のテーブルで起きること
- 投稿のタイトル・本文・抜粋に入れた絵文字は、WordPress が HTML の文字参照(
&#x...;の形)に置き換えて保存します。表示はされますが、データベースの中身は元の文字ではありません。 - それ以外の項目(カスタムフィールド、コメント、プラグインのテーブルなど)では、4バイトの文字を含む値の保存に失敗することがあります。
- テーブルが
latin1で、中身が日本語の場合は、phpMyAdmin などで見ると文字化けして見えることがあります(後の「latin1 のテーブルは注意」を参照)。
作業の前にバックアップを取る
文字コードの変換は、テーブルの中身を書き換えます。失敗したときに戻せるよう、先にデータベース全体のバックアップを取ります。
# WordPress のディレクトリで実行する
wp db export before-utf8mb4.sql
WP-CLI が使えない場合は、phpMyAdmin のエクスポートや、ホスティング会社のバックアップ機能を使います。大きなテーブルの変換には時間がかかり、その間テーブルへの書き込みが待たされることがあります。アクセスの少ない時間に作業し、できれば先にステージング環境で試します。
今の文字コードを調べる
phpMyAdmin の「SQL」タブ、または wp db query で次の SQL を実行します。DATABASE() は今接続しているデータベースです。
-- データベースの既定の文字コードと照合順序
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME = DATABASE();
-- テーブルごとの照合順序(utf8mb4_ で始まらないものが変換の対象)
SELECT TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
ORDER BY TABLE_NAME;
-- utf8mb4 以外の文字コードのカラム
SELECT TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND CHARACTER_SET_NAME IS NOT NULL
AND CHARACTER_SET_NAME <> 'utf8mb4'
ORDER BY TABLE_NAME, COLUMN_NAME;
WP-CLI で実行する場合は、SQL を wp db query "..." の引用符の中に入れます。最後の SQL で何も出なければ、カラムはすべて utf8mb4 です。
latin1 のテーブルは注意
latin1 のテーブルが見つかった場合は、変換の前に、中身が本当に latin1 の文字なのか、latin1 の箱に UTF-8 のバイト列が入っているだけなのかを確かめます。昔のサイトでは後者がよくあります。
SELECT ID, HEX(post_title) FROM wp_posts WHERE post_title <> '' LIMIT 5;
日本語のタイトルの16進数が E3 などで始まる3バイトの並び(たとえば「あ」は E38182)になっていて、WordPress の画面では正しく表示されている場合は、latin1 の箱に UTF-8 が入っています。このテーブルに次の節の CONVERT TO をそのまま実行すると、1バイトずつを latin1 の文字として変換するため、本当に文字化けします。この場合は別の手順が必要です。「WordPress のデータベースの文字化けを直す」を参照し、コピーしたデータベースで試してから本番に適用してください。
utf8(utf8mb3)のテーブルは、そのまま utf8mb4 に変換できます。utf8mb4 は utf8mb3 の文字をすべて含むためです。
データベースとテーブルを utf8mb4 に変換する
照合順序は utf8mb4_unicode_520_ci を使う例です。WordPress は、utf8mb4_unicode_ci を使う設定のとき、データベースが対応していれば utf8mb4_unicode_520_ci に切り替えて接続します。同じものに揃えておくと扱いやすくなります。
SQL で1つずつ変換する
-- データベースの既定(これから作るテーブルに使われる)
ALTER DATABASE `wordpress_db`
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_520_ci;
-- テーブルと、その中のカラムをまとめて変換する
ALTER TABLE `wp_posts`
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_520_ci;
wordpress_db と wp_posts は自分の環境のデータベース名・テーブル名に置き換えます。ALTER DATABASE は既定を変えるだけで、既にあるテーブルは変わりません。テーブルごとに ALTER TABLE ... CONVERT TO を実行します。テーブルの接頭辞(wp_ の部分)は wp-config.php の $table_prefix で確かめます。
WP-CLI でまとめて変換する
WP-CLI が使えるなら、wp db query を使うと wp-config.php の接続情報がそのまま使われ、パスワードをコマンドに書かずに済みます。WordPress のディレクトリで次のスクリプトを実行します。
#!/bin/bash
# WordPress の接頭辞が付いたテーブルを utf8mb4 に変換する
set -eu
COLLATION="utf8mb4_unicode_520_ci"
DB_NAME="$(wp config get DB_NAME)"
wp db query "ALTER DATABASE \`${DB_NAME}\` CHARACTER SET utf8mb4 COLLATE ${COLLATION};"
wp db tables --all-tables-with-prefix | while read -r table; do
echo "変換中: ${table}"
wp db query "ALTER TABLE \`${table}\` CONVERT TO CHARACTER SET utf8mb4 COLLATE ${COLLATION};"
done
echo "完了"
wp db tables --all-tables-with-prefixは、WordPress の接頭辞が付いたテーブル(プラグインが作ったものを含む)を1行に1つずつ出します。同じデータベースにある、接頭辞の違う別のアプリのテーブルは変換しません。set -eで、途中の変換が失敗したらそこで止まります。止まったテーブルのエラーを確かめてから続けます。latin1のテーブルがある場合は、このスクリプトを使う前に、前の節の確認をします。
ERROR 1071 が出たとき
ERROR 1071 (42000): Specified key was too long は、インデックスの長さが上限を超えたというエラーです。utf8mb4 は1文字を最大4バイトとして数えるため、VARCHAR(255) のカラムのインデックスは 1020 バイトになります。
- MySQL 5.7.9 以降・MariaDB 10.2.2 以降で、テーブルの行形式が
DYNAMIC(これらのバージョンの既定)なら、上限は 3072 バイトで、このエラーは通常出ません。 - それより古いバージョンや、行形式が
COMPACTのテーブルでは、上限が 767 バイトです。WordPress 本体のテーブルは、インデックスを先頭の191文字(764バイト)に絞って作られているため問題になりませんが、プラグインのテーブルでエラーになることがあります。
古いバージョンのデータベースを使っている場合は、データベースの更新を検討します。テーブルの行形式は次の SQL で確かめられます。
SELECT TABLE_NAME, ROW_FORMAT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE();
wp-config.php の設定
wp-config.php の文字コードの設定は、次のようにします。
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );
DB_CHARSETは、WordPress がデータベースに接続するときの文字コードです。今の WordPress は、utf8と書かれていてもutf8mb4に置き換えて接続します。そのため、wp-config.phpを書き換えるだけでは、テーブルの文字コードは変わりません。テーブルの変換が本体の作業です。DB_COLLATEは空のままにしておくと、WordPress が文字コードに合った照合順序を選びます(utf8mb4ならutf8mb4_unicode_ci、データベースが対応していればutf8mb4_unicode_520_ci)。特に理由が無ければ空のままにします。
wp-config.php の書き換えは、WordPress のファイルを編集するのと同じく、元のファイルを控えてから行います。
変換した後に確かめる
# utf8mb4 以外のテーブルが残っていないか(何も出なければ変換済み)
wp db query "SELECT TABLE_NAME, TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_COLLATION NOT LIKE 'utf8mb4%';"
# 接続の文字コード(character_set_client・connection・results が utf8mb4 か)
wp db query "SHOW VARIABLES LIKE 'character_set%';"
4バイトの文字がそのまま保存できるかは、テストの下書きを作って確かめます。次の例は、printf で絵文字を1文字作ってタイトルに入れ、保存されたバイト列を16進数で表示します。
# 絵文字を1文字入れた下書きを作り、投稿 ID を受け取る
ID=$(wp post create --post_title="$(printf 'utf8mb4 test \xF0\x9F\x98\x80')" --post_status=draft --porcelain)
# 保存されたタイトルを16進数で表示する
wp db query "SELECT HEX(post_title) FROM $(wp db prefix)posts WHERE ID = ${ID};"
# テストの下書きを消す
wp post delete "$ID" --force
結果の最後が F09F9880 なら、絵文字は4バイトのまま保存されています。262378316636... のように &#x を表す 26 23 78 が含まれる場合は、まだ utf8(utf8mb3)のカラムで、WordPress が文字参照に置き換えています。
MySQL・MariaDB の既定も utf8mb4 にする
自分で管理するサーバーでは、データベースサーバーの既定の文字コードも utf8mb4 にしておくと、後から作られるデータベースやテーブルが utf8mb4 になります。設定ファイル(Ubuntu の MySQL なら /etc/mysql/mysql.conf.d/mysqld.cnf、MariaDB なら /etc/mysql/mariadb.conf.d/50-server.cnf など)の [mysqld] に書きます。
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_520_ci
書き換えたら、データベースサーバーを再起動します。MySQL 8.0 以降の既定の文字コードは、最初から utf8mb4 です。共用のレンタルサーバーでは、この設定はホスティング会社が管理しているため変えられません。
注意事項
- 作業の前に
wp db exportなどでバックアップを取り、戻し方(wp db import before-utf8mb4.sql)を確かめておきます。 latin1のテーブルにCONVERT TOをそのまま実行すると、中身によっては文字化けします。先にHEX()で中身を確かめます。- 大きなテーブルの変換中は、サイトの書き込みが待たされることがあります。アクセスの少ない時間に作業します。
まとめ
information_schemaで、utf8mb4以外のテーブルとカラムを調べる- バックアップを取ってから、テーブルごとに
ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4を実行する(WP-CLI のwp db tables --all-tables-with-prefixとwp db queryでまとめて実行できる) latin1のテーブルは、中身が UTF-8 のバイト列でないかHEX()で確かめてから変換するwp-config.phpはDB_CHARSETをutf8mb4、DB_COLLATEを空にする。設定だけではテーブルは変わらない- テストの下書きで、絵文字が
F09F9880のまま保存されるか確かめる
照合順序の違いや、カラム単位での変更は「MySQL の文字コードと照合順序」で説明しています。