Будь ласка, поясніть, як Wordpress працює з набором символів і зіставленням MySQL на низькому рівні


10

Як показує заголовок питання, я хочу зрозуміти, як 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/ |
    +--------------------------+----------------------------+

Я б очікував, що набір символів бази даних буде UTF-8, а не latin1.

  1. Якщо я запускаю команду show variables like 'collation%';, вихід:

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

Це навіть дивніше, з очевидних причин (не очікував, що за замовчуванням порівняння latin1_swedish_ci в базі даних UTF-8).

  1. Нарешті, якщо я запускаю show full columns from mywpdatabase.wp_posts;, для вихідних рядків, у яких значення не є NULL, відображається порівняння:

| post_content_filtered | longtext | utf8mb4_unicode_ci |

Тоді моє запитання - як це можна пояснити? Чому в моєму Wordpress правильно встановлено символи UTF-8 MB4, коли база даних визначена як UTF-8 у конфігурації? І чому база даних відображається в MySQL як latin1, шведська зіставлення, а не UTF-8? І як так, що незважаючи на все це, окремі поля в таблиці є utf8mb4_unicode_ci? Пояснення на низькому рівні про те, як Wordpress працює з MySQL, було б дуже корисно. Дякую!

Відповіді:


11

На веб-сайті WordPress wp-config.php є два визначення:

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

Є кілька речей, які найчастіше неправильно розуміються. Імена констант у цих визначеннях можуть підказувати, що вони пов'язані з самою базою даних. Вони не. Вони пов'язані з таблицями в базі даних.

Створення бази даних абсолютно не залежить від створення таблиць. WordPress не створює базу даних і не піклується про набір символів та порівняння за замовчуванням, якщо він може підключитися до бази даних.

Значення 'utf8' у першому визначенні означає найменш обмежений набір символів із сімейства 'utf8', який є або 'utf8', або 'utf8mb4'.

Якщо ви залишаєте визначені вище незмінними, перед спробою встановлення вашого веб-сайту, це як сказати WordPress зробити свій власний вибір, щодо набору символів таблиць бази даних та порівняння, які підтримуються MySQL (залежно від версії MySQL) і є найменш обмежуючими.

Нижче описані речі, які WordPress аналізує, щоб визначити свій вибір під час встановлення:

  • Версія MySQL
  • порівняння бази даних (у wp-config.php)

На основі версії MySQL WordPress вирішує, яку групу сімейства utf8 використовувати. Є два, що відрізняються своїми назвами: utf8 та utf8mb4 . Набори символів з групи utf8 дозволяють зберігати не більше 3-байтних символів. Набори символів з групи utf8mb4 дозволяють зберігати не більше 4- байтних символів.

Тепер WordPress перевіряє значення DB_COLLATE визначення. Якщо порожній, він використовуватиме найменш обмежувальний порядок вибраного сімейства utf8 , інакше буде використане вказане значення.

Приклади

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 - помилка (невідповідність набору символів та зіставлення)

Підсумок

У більшості випадків залишати значення визначень, пояснених вище, незмінними, є хорошим вибором. Але, якщо ви хочете, щоб зіставлення таблиць відповідало мові вашого веб-сайту, ви можете змінити значення DB_COLLATE визначення, відповідним чином (наприклад - utf8mb4_polish_ci ).

Примітка: це пояснює, чому символ 𝌆 зберігався та знаходився належним чином. Просто ваш набір символів таблиць належав до групи utf8mb4 , а не utf8 .


1
Дякуємо, що пояснили, як Wordpress встановлює зіставлення, але ви не зверталися до решти питань. Чому, якщо визначено набір символів UTF-8, MySQL показує базу даних як латинську1? І чому він відображає зіставлення баз даних як шведське? Крім того, ви ніби заплутуєте набір символів і зіставлення. Збір визначає лише впорядкування, правила порівняння, а не набір символів. Отже, незалежно від того, яке поєднання використовується, якщо UTF-8 є набором символів, символи поза ним (як визначено у вужчому сенсі MySQL) не повинні відображатись.
X-Mann

Я оновлю свою відповідь, щоб більш чітко пояснити процес.
Френк П. Валентинович

1
Дякуємо за оновлення! Я прийняв вашу відповідь, зараз усе зрозуміло. Проблема полягає в MySQL і моєму недостатньому досвіді в цьому - я не знав, що таблиці можуть використовувати ширший набір символів, ніж сама база даних. Ця нова інформація налагодила мій погляд. Мені не потрібно змінювати набір символів за замовчуванням у MySQL, Wordpress піклується про це на рівні таблиці.
X-Mann

Будь ласка. Я радий, що це допомогло.
Френк П. Валентинович
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.