MySQL - символы utf8 не отображаются правильно в веб-интерфейсе - PullRequest
0 голосов
/ 11 января 2020

У меня есть база данных, которая имеет латинский набор символов по умолчанию - информация, полученная с помощью следующего оператора:

  SELECT default_character_set_name FROM information_schema.SCHEMATA 

WHERE schema_name = "schemaname";

Набор символов по умолчанию для каждого таблица и столбец в этой базе данных установлены в utf8.

Когда я смотрю на данные в таблицах, я вижу, что данные хранятся как utf8, например, символ валюты хранится в таблице как €. Точно так же апострафы хранятся как ’ et c.

На веб-интерфейсе у меня есть следующий метатег, и поэтому символы отображаются правильно.

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 

Однако я тоже видите много символов � на веб-странице, которые я не вижу внутри базы данных?

Когда я изменяю соединение с базой данных, чтобы включить кодировку utf8 следующим образом: mysql:host=myhost;dbname=mydatabase;charset=utf8, символы ромба исчезают, но затем все другие символы utf8 восстанавливаются точно так, как они сохраняются в базе данных, например, символ отображается как € на веб-странице?

Почему это происходит?

  1. Как это исправить, а также изменить набор символов на utf8mb4?

Любая помощь приветствуется.

* ОБНОВЛЕНИЕ *

Пробовал следующие шаги:

  1. для базы данных:

    ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

  2. Для каждой таблицы:

    ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

  3. Для каждого столбца:

    ALTER TABLE table_name CHANGE column_name column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Не уверен, что шаг 3 необходим, поскольку, когда я делаю SHOW CREATE TABLE после шага 2, хотя определение не отображает кодировку столбца, оно отображает кодировку по умолчанию для таблицы как utf8mb4. В качестве проверки работоспособности я выполнил шаг 3 для одного из столбцов таблиц, но это не имеет значения - € отображается на странице как € с подключением к БД следующим образом:

`mysql:host=myhost;dbname=mydatabase;charset=utf8mb4`

I пришлось выполнить следующее в каждом столбце, который я хотел преобразовать, что, по-видимому, решает некоторые проблемы

 UPDATE tbl_profiles SET profile =
 convert(cast(convert(profile using latin1) as binary) using UTF8MB4);

, но все еще видит символы, такие как Iâm и « и â¢, отображаемые на веб-странице

Есть идеи?

* ОБНОВЛЕНИЕ 2 *

После выполнения шагов 1 и 2 выше у меня есть столбец таблицы следующим образом:

`job_salary` VARCHAR(150) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',

Следующий запрос к этому столбцу возвращает следующий результат:

SELECT job_salary FROM tbl_jobs WHERE job_id = 2235;

€30,000 plus excellent benefits 

Я выполняю следующий оператор для этого столбца:

UPDATE tbl_jobs SET job_salary = CONVERT(BINARY(CONVERT(job_salary  USING latin1)) USING utf8mb4);

Но я получаю следующую ошибку, которая означает некоторые другие запись содержит недействительный utf8mb4

Invalid utf8mb4 character string: '\x8010000 to \x8020000 Per: annum'

1 Ответ

0 голосов
/ 15 января 2020

Сначала давайте обсудим моджибаке со знаком евро. Все это относится как к utf8, так и к utf8mb4, поскольку евро кодируется одинаково и .

Весьма вероятно, что данные изначально были сохранены неверно. Если вы можете вернуться к программе INSERT, давайте проверим:

  • Сохраняемые байты должны быть в кодировке UTF-8. Какой был язык программирования клиента? Откуда поступили данные?
  • Соединение при вставке и выделении текста должно указывать utf8 или utf8mb4. У вас есть параметры подключения?
  • Столбец должен быть объявлен CHARACTER SET utf8 (или utf8mb4). Звучит так, будто это всегда правильно.
  • HTML должно начинаться с.

Что в данный момент в таблице ?

SELECT col, HEX(col) FROM ... WHERE ...

Правильно сохраненный знак евро () должен иметь шестнадцатеричное значение E282AC. (Интерпретируя это, так как latin1 дает €.

Если вместо этого вы видите hex C3A2E2809AC2AC, у вас есть «двойное кодирование», и на дисплее, вероятно, €.

У меня есть определили несколько возможных исправлений , но еще не определили, что применимо в вашем случае. Вероятным кандидатом является

  • CHARACTER SET utf8mb4 с двойным кодированием:

Чтобы проверить это (перед исправлением), сделайте что-то вроде:

SELECT col,
       CONVERT(BINARY(CONVERT(col USING latin1)) USING utf8mb4),
       HEX(    
          CONVERT(BINARY(CONVERT(col USING latin1)) USING utf8mb4)
          )
    FROM ...
    WHERE ...

Не применяйте исправление поверх другого исправления . Я долго пытался расшифровать, как возникают проблемы с наборами символов и что нужно сделать, чтобы «исправить» одну проблему, но когда применяется неправильное исправление, я не могу распутать беспорядок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...