Переход с latin1 на utf8 на сервере mysql

Недавно мы начали получать 'utf8' codec can't decode bytes in position 30-31: unexpected end of data при сборе данных из базы данных (используя Python и SQLAlchemy). Мы обнаружили ошибку в некоторых специальных японских символах.

Все таблицы имеют CHARSET=utf8, и это настройки, которые у нас есть на сервере, когда я запускаю show variables;

| character_set_client                    | latin1
| character_set_connection                | latin1
| character_set_database                  | latin1
| character_set_filesystem                | binary
| character_set_results                   | latin1
| character_set_server                    | latin1
| character_set_system                    | utf8
| character_sets_dir                      | /usr/share/mysql/charsets/
| collation_connection                    | latin1_swedish_ci
| collation_database                      | latin1_swedish_ci
| collation_server                        | latin1_swedish_ci

Если мы не хотим переводить нашу среду на utf8 — какие настройки рекомендуются и как мы должны экспортировать и импортировать текущие данные, которые у нас есть, чтобы заставить их работать с новыми настройками?

Я прочитал несколько сообщений об экспорте данных как latin1 путем добавления --default-character-set=latin1 в команду mysqldump, а затем импорта их в базу данных с новыми настройками, но, поскольку наши исходные таблицы уже находятся в utf8, это не сработает.

Попытался установить соединение после прочтения этой темы: SQLAlchemy и UnicodeDecodeError

Это решает проблему сбоя приложения, но все старые данные повреждаются.


person Carl    schedule 02.12.2013    source источник
comment
На самом деле у вас есть данные latin1. Вам нужно получить его, закодировать в UTF-8, а затем повторно импортировать в таблицу сопоставления UTF-8. Я не думаю, что вы можете просто изменить кодировку для базы данных и таблиц. Не забудьте также установить соединение с UTF-8 в конфигурации или с помощью SET NAMES. а ты сделай бэкап и попробуй просто сконвертировать?   -  person Daniel W.    schedule 02.12.2013
comment
Попробовал настроить соединение, решает сбой приложения, но повреждает старые данные. Я обновил вопрос.   -  person Carl    schedule 02.12.2013
comment
Итак, если таблицы имеют кодировку utf8 и соединение latin1, фактические данные по-прежнему хранятся как latin1? @DanFromGermany   -  person Carl    schedule 02.12.2013
comment
Как правило, смешивать кодировки — плохая идея. Это как сравнивать файлы EXE и PDF - нельзя. У них разные байты, разные символы имеют разную длину байта, разные заголовки (например, спецификацию). Когда у вас есть таблица UTF-8 и вы извлекаете данные с помощью PHP, используя соединение latin1, вы получите данные utf-8 в переменной latin1, данные будут повреждены.   -  person Daniel W.    schedule 02.12.2013
comment
Вы также можете столкнуться с двойным кодированием. Лучшим ресурсом для вас в этом случае является блог производительности, авторами которого являются, например, разработчики ядра MariaDB, Percona, InnoDB: mysqlperformanceblog.com/2013/10/16/   -  person Daniel W.    schedule 02.12.2013


Ответы (1)


Вы можете преобразовать сопоставление таблиц с помощью одного запроса, например:

ALTER TABLE <yourtable> CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
person Eshant Sahu    schedule 20.03.2014