web-dev-qa-db-ja.com

WordpressがMySQLの文字セットと照合順序を低レベルでのように機能するかを説明してください

質問のタイトルが示唆するように、私はWordpressがMySQLの文字セットと照合オプションでどのように機能するかを理解しようとしています。以下に示すように、物事は私にとってあまり意味がありません...

インストールページの指示に従ってWordpressをインストールしました。

https://codex.wordpress.org/Installing_WordPress

説明の一部として、MySQLデータベースを手動で作成するためのコマンドライン、つまりコマンドに関するアドバイスに従いました。

mysql> CREATE DATABASE databasename;
Query OK, 1 row affected (0.00 sec)

mysql> GRANT ALL PRIVILEGES ON databasename.* TO "wordpressusername"@"hostname"
-> IDENTIFIED BY "password";
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

mysql> EXIT

さらに、指示されたように、私は "wp-config.php"ファイルを編集してUTF-8文字セットを使用しました。

define( 'DB_CHARSET', 'utf8' );

...そして照合設定を空白のままにします。

define( 'DB_COLLATE', '' );

これが楽しみの始まりです。

  1. MySQL UTF-8の一部ではないが、????などのUTF-8 MB4の一部である文字を投稿に入力すると、レンダリングされたページに正しく表示されます。私は文字セットをUTF-8 MB4に設定していないので、これは起こらないと予想していましたが、より制限されたUTF-8(もちろんMySQLによって定義されているように、一般に理解されていない)。

  2. コマンドラインでMySQLの問題を調査した場合、それは奇妙になります。 show variables like 'char%';を実行すると、次のようになります。

    +--------------------------+----------------------------+
    | Variable_name            | Value                      |
    +--------------------------+----------------------------+
    | character_set_client     | utf8                       |
    | character_set_connection | utf8                       |
    | character_set_database   | latin1                     |
    | character_set_filesystem | binary                     |
    | character_set_results    | utf8                       |
    | character_set_server     | latin1                     |
    | character_set_system     | utf8                       |
    | character_sets_dir       | /usr/share/mysql/charsets/ |
    +--------------------------+----------------------------+
    

データベースの文字セットはlatin1ではなくUTF-8になるはずです。

  1. コマンドshow variables like 'collation%';を実行すると、出力は次のようになります。

    +----------------------+-------------------+
    | Variable_name        | Value             |
    +----------------------+-------------------+
    | collation_connection | utf8_general_ci   |
    | collation_database   | latin1_swedish_ci |
    | collation_server     | latin1_swedish_ci |
    +----------------------+-------------------+
    

明らかな理由から、これはさらに奇妙なことです(UTF-8データベースではデフォルトのlatin1_swedish_ci照合順序は想定されていなかったでしょう)。

  1. 最後に、show full columns from mywpdatabase.wp_posts;を実行した場合、値がNULLではない出力行では、照合順序を次のように表示します。

| post_content_filtered | longtext | utf8mb4_unicode_ci |

それでは私の質問 - これはどのように説明できるのでしょうか?データベースが設定でUTF-8として定義されているのに、なぜ私のWordpressはUTF-8 MB4文字を正しくレンダリングするのですか?また、データベースがMySQLでUTF-8ではなくlatin1、スウェーデン語の照合順序として表示されるのはなぜですか。それにしても、これにもかかわらず、テーブル内の個々のフィールドはutf8mb4_unicode_ciです。 WordpressがMySQLとどのように連携しているかについての低レベルの説明が非常に役立ちます。ありがとうございました!

9
X-Mann

WordPress Webサイトのwp-config.phpには2つの定義があります。

define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');

最も一般的に誤解されていることがいくつかあります。それらの定義の中の定数の名前は、それらがデータベース自体に関連していることを示唆するかもしれません。ではない。それらはデータベース内のテーブルに関連しています。

データベースの作成はテーブルの作成から完全に独立しています。データベースに接続できる限り、WordPressはデータベースを作成せず、データベースのデフォルトの文字セットと照合順序については考慮しません。

最初の定義の値 'utf8'は、 'utf8'または 'utf8mb4'のいずれかである 'utf8'ファミリーからの最も制限の少ない文字セットを意味します。

Webサイトをインストールする前に上記の定義を変更しないでおくと、MySQLでサポートされているデータベースのテーブルの文字セットと照合順序に関して、WordPressに独自の選択を行わせるように指示されます。

以下は、インストール中にWordPressがその選択を決定するために分析するものです。

  • MySQLのバージョン
  • データベースの照合(wp-config.php内)

MySQLのバージョンに基づいて、WordPressは、 utf8 familyのどのグループを使用するかを決定します。それらの名前によって区別される2つがあります: utf8 utf8mb4 utf8 groupの文字セット。最大3バイトの長さの文字を格納できます。 utf8mb4 groupの文字セット。最大4バイトの長さの文字を格納できます。

さて、WordPressは DB_COLLATE defineの値をチェックします。空の場合は、選択された utf8 familyからの制限が最も少ない照合が使用されます。それ以外の場合は、指定された値が使用されます。

define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');

MySQLが utf8mb4 (古いバージョン)をサポートしていない場合、テーブルの文字セットは utf8 になり、照合順序は utf8_general_ci になります。そうでなければ、それぞれ utf8mb4 utf8mb4_unicode_520_ci 、または utf8mb4_unicode_ci (MySQLのバージョンに依存)が期待できます。

define('DB_CHARSET', 'utf8');
define('DB_COLLATE', 'utf8_polish_ci');

古いMySQLバージョン - utf8 および utf8_polish_ci 。新しいMySQLのバージョン - utf8mb4 および utf8mb4_polish_ci _polish_ci の接尾辞が使用できます)

define('DB_CHARSET', 'cp1250');
define('DB_COLLATE', 'cp1250_polish_ci');

任意のMySQLバージョン - cp1250 および cp1250_polish_ci

define('DB_CHARSET', 'cp1250');
define('DB_COLLATE', 'utf8_general_ci');

MySQLの全バージョン - エラー(文字セットと照合順序の不一致)

概要

ほとんどの場合、上で説明したdefineの値を変更しないでおくのが良い選択です。ただし、テーブルの照合順序をWebサイトの言語と一致させるには、 DB_COLLATE defineの値を適切に変更します(たとえば、 - utf8mb4_polish_ci )。

注: 説明が付いているのはなぜ文字なのでしょうか。適切に保管および検索されました。簡単に言えば、あなたのテーブルの文字セットは utf8 groupではなく utf8mb4 groupに属していました。