WPML

Что такое кодировки и правила сравнения в MySQL?

Когда WordPress сохраняет контент Вашего сайта в базе данных (например, записи, заголовки, переведенные строки и т. д.), он использует кодировку для представления символов и правила сравнения для определения того, как эти символы сравниваются и сортируются.

Кодировка (Charset)
Определяет, как символы хранятся в базе данных — по сути, какие байты представляют какие символы.
Правила сравнения
Определяют правила сравнения этих символов (например, чувствительность к регистру, чувствительность к диакритическим знакам и порядок сортировки).

Почему это важно для мультиязычных сайтов

WPML поддерживает мультиязычный контент, который часто включает:

  • Специальные символы (например, ñ, é, ö)
  • Нелатинские алфавиты (например, арабский, японский, китайский, иврит)
  • Эмодзи и символы (🎉, ✔️ и т. д.)

Многие из них требуют более 3 байтов для правильного хранения. Если Ваша база данных использует несовместимые правила сравнения, символы могут быть потеряны, заменены на «?» или вызывать ошибки базы данных (например, «Incorrect string value»).

Поэтому мы настоятельно рекомендуем использовать правила сравнения, поддерживающие 4-байтовые символы Unicode.

Наши рекомендации

Используйте кодировку utf8mb4 и совместимые с Unicode правила сравнения, такие как:

  • utf8mb4_unicode_ci — широкая совместимость, хороший выбор по умолчанию
  • utf8mb4_unicode_520_ci — лучшая обработка Unicode в MySQL 5.6+
  • utf8mb4_general_ci — немного быстрее, но менее точное сравнение Unicode
  • utf8mb4_bin — чувствительность к регистру и диакритическим знакам (бинарное сравнение)

Все они безопасны для использования с WPML.


Важно: старая кодировка utf8 в MySQL поддерживает только до 3 байтов на символ. Она не может обрабатывать некоторые символы, такие как эмодзи или некоторые идеограммы. Избегайте ее использования для мультиязычного контента.

Что используется в MySQL по умолчанию?

Версия MySQLКодировка по умолчаниюПравила сравнения по умолчаниюСовместимость с Unicode
< 5.5latin1latin1_swedish_ciНет
5.5.xutf8utf8_general_ciНет
5.7+utf8mb4utf8mb4_general_ci / utf8mb4_unicode_ciДа
8.0+utf8mb4utf8mb4_0900_ai_ciДа

WordPress не всегда следует настройкам MySQL по умолчанию — он может переопределять их через конфигурацию или миграции.

Настройка кодировки и правил сравнения для новых сайтов

Чтобы WordPress создавал новые таблицы с правильной кодировкой и правилами сравнения, укажите следующее в Вашем файле wp-config.php:

define( 'DB_CHARSET', 'utf8mb4' ); // If you have utf8 that's fine, WP will automatically map it as utf8mb4
define( 'DB_COLLATE', 'utf8mb4_unicode_ci' );

Это будет применяться к новым установкам и вновь созданным таблицам.

Проверка кодировки и правил сравнения для существующих сайтов и таблиц

Вот как проверить кодировку и правила сравнения на Ваших существующих сайтах.

Вариант 1 phpMyAdmin

  1. Перейдите в базу данных Вашего сайта.
  2. Проверьте столбец «Сравнение» рядом с каждой таблицей.
  3. Нажмите на таблицу, чтобы просмотреть индивидуальные правила сравнения каждого столбца.

Вариант 2 WP-CLI

bash

wp db query "SELECT TABLE_NAME, TABLE_COLLATION FROM information_schema.tables WHERE table_schema = 'your_db_name';"

Вы также можете проверить отдельные столбцы:

bash

wp db query "SHOW FULL COLUMNS FROM wp_posts;"

Если Вы видите, что правила сравнения начинаются с utf8mb4_, значит, они готовы к поддержке всех типов Unicode и 4-байтовых идеограмм. Кодировка также подходит.

Если Вы видите что-то другое, например utf8_*, то Вам нужно это изменить.

Обратите внимание, что правила сравнения могут отличаться для разных столбцов.

Обновление кодировки и правил сравнения для существующих таблиц и столбцов

Обновление констант DB_CHARSET и DB_COLLATE в Вашем файле wp-config.php влияет только на новые таблицы. Чтобы применить изменения к существующим таблицам и столбцам, Вы должны преобразовать их вручную с помощью SQL.

Мы также рекомендуем обновить правила сравнения базы данных MySQL по умолчанию с помощью следующей команды:

ALTER DATABASE your_database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Всегда начинайте с резервного копирования

Перед выполнением любых запросов на преобразование:

  • Экспортируйте Вашу базу данных с помощью phpMyAdmin или mysqldump
  • Сохраните ее в надежном месте на случай, если что-то пойдет не так

Предупреждение: обновления правил сравнения могут завершиться ошибкой в строгом режиме

При обновлении правил сравнения всей таблицы (или базы данных) MySQL может перестроить таблицы и повторно проверить все значения столбцов по умолчанию — включая несвязанные, такие как DATETIME. Если Ваша база данных работает в строгом режиме SQL (STRICT_TRANS_TABLES, NO_ZERO_DATE), столбцы со значениями по умолчанию, такими как «0000-00-00 00:00:00», будут вызывать ошибки, например:

#1067 - Invalid default value.

Что такое строгий режим?

Строгий режим контролирует, как MySQL обрабатывает недопустимые или отсутствующие значения при добавлении или обновлении данных в базе данных. Значение может быть недопустимым по нескольким причинам. Например, оно может иметь неправильный тип данных для столбца или выходить за пределы допустимого диапазона.

Вы можете найти информацию о различных типах проверки данных для строгого режима в документации MySQL.

Как строгий режим влияет на базу данных сайта WordPress

По умолчанию WordPress использует «0000-00-00 00:00:00» в качестве значения по умолчанию для некоторых столбцов datetime, что не принимается строгим режимом NO_ZERO_DATE.

Обратите внимание, что эти значения по умолчанию были разрешены во время первоначального создания таблицы (например, во время установки WordPress), но вызывают ошибку при операциях ALTER в строгих средах.

Как проверить, включен ли строгий режим

Выполните следующую команду:

SELECT @@SESSION.sql_mode, @@GLOBAL.sql_mode;

Ищите:

  • STRICT_TRANS_TABLES
  • STRICT_ALL_TABLES
  • NO_ZERO_DATE

Если Вы найдете что-либо из этого, строгий режим включен.

Чтобы избежать ошибок во время обновления кодировки и правил сравнения, Вам нужно отключить только строгий режим NO_ZERO_DATE.

Как безопасно продолжить работу

Выполните одно из следующих действий, чтобы безопасно продолжить работу:

1. Избегайте изменения столбцов и таблиц, если правила сравнения действительно не нуждаются в изменении.

2. Временно отключите строгий режим только для сеанса во время выполнения запросов на преобразование. Вы можете сделать это с помощью следующей команды:

SET SESSION sql_mode = REPLACE(@@sql_mode, 'NO_ZERO_DATE', '');

Примечание: в планах на будущее для MySQL предусмотрено объединение строгих режимов.

В случае других проблем, характерных для Ваших данных, Вы можете отключить любой строгий режим с помощью следующей команды:

SET SESSION sql_mode = '';

Запросы для преобразования данных

Преобразование всей базы данных

Следующий код генерирует запрос ALTER TABLE для каждой таблицы в Вашей базе данных:

SELECT CONCAT(
  'ALTER TABLE `', TABLE_NAME, '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'
) AS query
  FROM INFORMATION_SCHEMA.TABLES
  WHERE TABLE_SCHEMA = 'your_database_name';

Выполните полученные запросы в phpMyAdmin или скопируйте и вставьте их в MySQL CLI / WP-CLI.

Это гарантирует, что все таблицы в Вашей базе данных примут новую кодировку и правила сравнения.

Преобразование определенной таблицы Необязательно / Дополнительно
ALTER TABLE wp_posts 
  CONVERT TO CHARACTER SET utf8mb4 
  COLLATE utf8mb4_unicode_ci;

Это обновит все текстовые столбцы в таблице wp_posts для использования utf8mb4 и указанных правил сравнения.


Преобразование определенного столбца Необязательно / Дополнительно
ALTER TABLE wp_posts 
  CHANGE post_title post_title TEXT 
  CHARACTER SET utf8mb4 
  COLLATE utf8mb4_unicode_ci;

Примечание:

  • Вы должны полностью переобъявить столбец (тип, имя) в CHANGE.
  • Убедитесь, что тип столбца совпадает с существующим.

Распространенные ошибки при преобразовании

Вот две распространенные ошибки, с которыми Вы можете столкнуться при преобразовании таблиц и столбцов.

Несовпадение кодировки и правил сравнения
-- INVALID: utf8 collation with utf8mb4 charset
ALTER TABLE wp_posts CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8_general_ci;
-- Error: COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'utf8mb4'

Решение:

  • Используйте соответствующие правила сравнения: utf8mb4_*

Ограничение длины ключа индекса
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

В некоторых конфигурациях, особенно для версий MySQL ниже 5.7, максимальная длина ключа индекса может быть превышена при добавлении еще одного байта на символ.

Решение:

  • При необходимости сократите индексированный VARCHAR(255) до VARCHAR(191)
  • Или обновитесь до MySQL 5.7+ и убедитесь, что включен параметр innodb_large_prefix

Краткие итоги

  • Используйте кодировку utf8mb4 для полной поддержки Unicode
  • Используйте совместимые правила сравнения: utf8mb4_unicode_ci, utf8mb4_0900_ai_ci и т. д.
  • Обновите wp-config.php для новых таблиц
  • Выполните миграции SQL для исправления существующих таблиц
  • Никогда не смешивайте кодировки и правила сравнения — MySQL отклонит или повредит их.