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 の文字コードと照合順序」で説明しています。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲