WordPressと

MySQLの文字照合順序

宇都宮 諒(@ryo511)

WordPressもくもく勉強会@日本橋 #11

2017-11-18

自己紹介

一休コンシェルジュ

  • 上質なホテル・旅館を紹介するメディア
  • powered by WordPress!

文字の照合順序

  • 照合順序(collation)
    • 文字セット内の文字を比較するためのルール
  • 文字セット(character set)
    • 記号とエンコーディングのセット

具体的に

ABab」の4つの文字からなる

文字セットを考えてみる

それぞれの文字に以下のように数字を割り当てる

A=0 B=1 a=2 b=3

※Aが記号、0がエンコーディング

同じ文字かどうかを調べる際、

エンコーディングだけを見るのが一番簡単

(バイナリ照合順序)

Beyond binary

Aと「a」を同一視したい場合はどうすればよいか?

→ 文字を比較する際に追加のルールを定めればよい

→ このルールには様々なものがある

代表的な照合順序

utf8mb4_unicode_(520)_ciは

「ハハ」と「パパ」を区別しない 😇

WordPressは…

// wp-includes/wp-db.php L713~
public function determine_charset( $charset, $collate ) {
  // 中略
  if ( 'utf8mb4' === $charset ) {
    // _general_ is outdated, so we can upgrade it to _unicode_, instead.
    if ( ! $collate || 'utf8_general_ci' === $collate ) {
      $collate = 'utf8mb4_unicode_ci';
    } else {
      $collate = str_replace( 'utf8_', 'utf8mb4_', $collate );
    }
  }
  // _unicode_520_ is a better collation, we should use that when it's available.
  if ( $this->has_cap( 'utf8mb4_520' ) && 'utf8mb4_unicode_ci' === $collate ) {
    $collate = 'utf8mb4_unicode_520_ci';
  }
  return compact( 'charset', 'collate' );
}

ut8mb4_unicode_520_ci の優先度が最も高い

普通にインストールしたらunicode_ci

ハハ ≠ パパ にしたい

  • どの照合順序を使えばいいの?
    • utf8mb4_general_ci
    • utf8mb4_bin
    • utf8mb4_ja_0900_as_cs ※ MySQL 8.0以上
  • どうやって設定するの?
    • インストール前:wp-config.phpでDB_COLLATE定数を定義してからインストールすればいいらしい
    • インストール後:データベースとテーブルの照合順序設定を変える(後述)

照合順序の変更

  • 影響範囲が大きいので慎重に。バックアップ必須。
  • 以下のようなSQLを実行すれば変更できる
-- データの整合性確認を一時的に弱める(永続化はされないので戻さなくてもOK)
SET foreign_key_checks = 0; -- 外部キー制約を無効化・要らないかも
SET sql_mode = ''; -- sql_modeのNO_ZERO_IN_DATEを無効化

ALTER DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

-- プラグインをインストールしている場合、プラグイン用のテーブルにも変更が必要な点に注意!
ALTER TABLE wp_commentmeta CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ALTER TABLE wp_comments CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ALTER TABLE wp_links CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ALTER TABLE wp_options CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ALTER TABLE wp_postmeta CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ALTER TABLE wp_posts CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ALTER TABLE wp_term_relationships CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ALTER TABLE wp_term_taxonomy CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ALTER TABLE wp_termmeta CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ALTER TABLE wp_terms CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ALTER TABLE wp_usermeta CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ALTER TABLE wp_users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

MySQL 8.0

  • 2017/11/18 現在Release Candidate
  • utf8mb4_ja_0900_as_cs という照合順序が追加された
    • A != a
    • ハハ ≠ パパ
    • 🍣 ≠ 🍺

まとめ

  • 文字の照合順序は重要
  • WordPressのデフォルトは ハハ = パパ
  • MySQL 8.0早く使いたい

WordPressとMySQLの文字照合順序

By Ryo Utsunomiya

WordPressとMySQLの文字照合順序

WordPressもくもく勉強会@日本橋 #11

  • 2,953