Время на прочтение
3 мин
Количество просмотров 22K
В связи с тем, что довольно много людей обращается с просьбой помочь исправить проблему с кодировками MySQL, решил написать статью с описанием, как «лечить» наиболее часто встречающиеся случаи.
В статье описывается не то, как первоначально правильно настроить кодировки MySQL (об этом уже довольно много написано), а о случаях, когда есть довольно большие таблицы с неправильными кодировками и нужно всё исправить.
Самое плохое в неправильно настроенных кодировках — то, что зачастую проблему сложно обнаружить, и с первого взгляда может казаться, что сайт работает правильно, и никаких проблем нет.
Небольшое отступление. Sypex Viewer
В какой-то момент надоело отправлять людей в громоздкий phpMyAdmin, и была написана крошечная утилитка Sypex Viewer. Она представляет собой один PHP-файл, использует современные Web 2.0 технологии AJAX, JSON и другие. Основные задачи, которые ставилась при создании — минимальный вес, и максимальное удобство и скорость работы. В дальнейшем в примерах будут скриншоты из неё, но все те же действия можно сделать и в phpMyAdmin.
Данные в cp1251 таблицы в latin1
Наверное, самая популярная проблема. Когда данные в кодировке cp1251 (Windows-1251), а у таблиц указана кодировка по умолчанию latin1. Такие ситуации возникают в следующих случаях:
- при неграмотном обновлении с версии MySQL меньше 4.1 на более новые;
- очень часто возникает в «буржуйских» скриптах, которых вполне устраивает кодировка по умолчанию, и они «забывают», что неплохо бы указывать кодировку, как таблиц, так и соединения;
- также бывают случаи, когда переезжают с одного сервера (у которого установлена дефолтная кодировка cp1251, в частности, так сделано в Денвере) на другой (у которого стоит стандартная кодировка latin1).
В результате на сайте вроде как всё нормально, но если посмотреть в Sypex Viewer, то русские символы будут выглядеть как «кракозябры» (как их обычно называют пользователи).
В статье я рассмотрю один из вариантов преобразование кодировок с помощью бесплатного php-скрипта Sypex Dumper, в качестве готового решения.
- На вкладке «Экспорт» выбираем нужные таблицы.
- Кодировка должна быть auto (остальные параметры неважны, можно комментарий добавить, например, «Дамп перед исправлением кодировки»).
- Нажимаем «Выполнить». Теперь у нас есть бэкап (его в любом случае желательно делать при любых преобразованиях базы данных).
- Переходим на вкладку «Импорт»
- Выбираем только что сделанный файл бэкапа.
- Выбираем кодировку cp1251 и помечаем опцию «Коррекция кодировки».
- Нажимаем «Выполнить».
- Вот и всё заходим в Sypex Viewer, чтобы убедиться, что русские символы выводятся корректно.
Данные и таблицы в utf8, но кодировка соединения latin1
Теперь рассмотрим более запущенный случай. Набирающая популярность в последнее время проблема, в связи с повальным увлечением UTF-8. Создатели софта стали переводить свои детища на UTF-8, но и тут не всё так гладко, как хотелось бы.
Возникает проблема в основном в случае, когда у таблиц указана кодировка UTF-8, данные в UTF-8, но кодировка соединения установлена по умолчанию latin1 (типичный пример, vBulletin 4, хоть там и есть в конфигах настройка кодировки соединения, но она закомментирована по умолчанию).
В результате в MySQL присылаются данные в UTF-8, но поскольку указана кодировка соединения latin1, то MySQL пытается преобразовать данные из latin1 в UTF-8. В итоге русские символы выглядят так:
Ситуация более запущенная, но исправляется проблема почти также, как в первом случае, только в пункте 2 нужно выбрать кодировку latin1, а в пункте 6 нужно выбрать utf8 кодировку.
Изменение кодировки
Также часто встречающаяся проблема преобразования кодировки из cp1251 в UTF-8. До выполнения этого шага обязательно убедитесь, что русские символы у вас правильно показываются в Sypex Viewer или phpMyAdmin, если это не так, то предварительно исправьте кодировку.
Итак, опять заходим в Sypex Dumper.
- Во вкладке «Экспорт» выбираем нужные таблицы.
- Устанавливаем кодировку, в которую хотите преобразовать таблицы, в данном случае utf8.
- Нажимаем «Выполнить».
- После чего заходим в «Импорт» и выбираем нужный файл.
- Выставляем кодировку utf8 и опцию «Коррекция кодировки».
- Нажимаем «Выполнить».
- Вот и всё таблицы в UTF-8. Не забываем, что нужно еще установить кодировку соединения, сконвертировать ваши скрипты и шаблоны в UTF-8, выставить правильную кодировку в заголовках.
Кодировка соединения
Не забываем, что после исправлений кодировки, нужно убедиться, что ваши скрипты используют правильную кодировку соединения (в принципе, это будет сразу видно, они будут неправильно показывать русские символы без нужной кодировки соединения). У некоторых она выставляется в настройках, в некоторых придется добавить самостоятельно.
Для чего достаточно пройтись поиском по файлам, и найти где вызывается функция mysql_connect (или mysqli_connect). После этой строки нужно добавить строку которая укажет кодировку соединения.
mysql_query("SET NAMES 'cp1251'");
Где вместо cp1251, указать нужную кодировку соединения.
Не забывайте перед преобразованиями кодировок делать бэкап, тут как с презервативами, лучше пусть он будет и не понадобится, чем когда понадобится — его не будет.
P.S. Спасибо Шортикам за веселый контент для примеров.
-
Помощь -
Хостинг -
Базы данных -
Как изменить кодировку для всех таблиц в MySQL
Вы установили MySQL, создали таблицы и наполнили их данными, а в ответ отображается «абракадабра»? Дело в неправильно указанной кодировке. Для того чтобы данные отображались корректно, нужно изменить параметр кодировки для каждой таблицы.
В базе данных могут быть сотни таблиц, поэтому воспользуйтесь следующим решением для оперативной смены кодировок:
-
1.
Войдите в phpMyAdmin и выберите необходимую базу данных из списка, кликнув по её названию:
-
2.
В столбце «Сравнение» отображается сопоставление кодировки базы данных:
-
3.
Скопируйте запрос ниже:
SELECT CONCAT('ALTER TABLE `', t.`TABLE_SCHEMA`, '`.`', t.`TABLE_NAME`, '` CONVERT TO CHARACTER SET нужная_кодировка COLLATE сопоставление;') as sqlcode FROM `information_schema`.`TABLES` t WHERE 1 AND t.`TABLE_SCHEMA` = 'имя_базы' ORDER BY 1
где:
-
нужная_кодировка — кодировка, которую нужно применить;
-
сопоставление — сопоставление кодировки базы данных (шаг 2 — столбец «Сравнение»);
-
имя_базы — имя базы данных.
-
- 4.
-
5.
Вставьте запрос из шага 3 в окно запроса MySQL и выполните его, нажав Вперёд. В примере ниже мы сформировали список запросов для всех таблиц базы данных, который нужно выполнить, чтобы изменить кодировку на utf8 и на сопоставление кодировки utf8_general_ci.
-
6.
В качестве ответа на запрос появится список запросов для смены кодировки каждой таблицы. Раскройте вкладку Параметры, установите чекбокс напротив пункта Полные тексты и нажмите Вперёд:
- 7.
-
8.
Вернитесь на вкладку SQL. Вставьте запросы в окно запроса MySQL и нажмите Вперёд:
Готово, вы успешно изменили кодировку во всех таблицах базы данных.
Спасибо за оценку!
Как мы можем улучшить статью?
Нужна помощь?
Напишите в службу поддержки!
ZEL-Услуги
»Пресс-центр
»Статьи
»В MySQL знаки вопросов вместо русских букв — решение проблемы с кодировкой
26.04.2019
При переносе дампа или после нескольких манипуляций в базе неожиданно появились знаки вопросов в MySQL вместо русских букв? Это известная и распространённая проблема в MySQL старших версий.
Это руководство поможет предпринять быстрые шаги в исправлении ситуации.
Мы рассмотрим конкретные действия для быстрого решения. Обратите внимание на официальное руководство по кодировке в MySQL, чтобы вы смогли разбираться в сути и выполнять рекомендации осознанно.
Исправляем знаки вопросов в MySQL на русские буквы
Воспользуйтесь этими быстрыми рекомендациями, чтобы отобразить русские буквы без знаков вопросов и «крякозябр». Ниже мы привели некоторые уточнения.
-
Дождитесь выполнения соединения с сервером
-
Введите запрос:
set names кодировка«кодировка» — это параметр кодировки, в которой вы выводите данные страницы на сайте.
То есть запрос для UTF-8 должен выглядеть так:
set names utf8А для Windows-1251 вот так:
set names cp1251 -
Очень часто параметр «Set Names» не помогает решить проблему кодировке при сортировке по имени, хотя буквы отображаются нормально. Как это исправить, читайте далее.
Обратите внимание, что запросы «set names» по факту не влияют на кодировку, которая используется функцией mysql_real_escape_string. Поэтому рекомендуется применять установку кодировки через mysql_set_charset() вместо запроса «set names». Но даже если вы проигнорируете эту рекомендацию, то для Uta8 и других однобайтных кодировок ничего плохого не последует.
Чтобы не задавать кодировку в каждом скрипте, допишите в my.ini
[mysqld]
init-connect=’SET NAMES utf8′
Исправление проблемы кодировки MySQL, если запрос SET NAMES не помог
Перед тем, как изменить кодировку MySQL, вновь выполните запрос «Set Names», но уже с указанием кодировки таблицы (мы должны её выяснить).
-
Причина кроется в том, что для таблиц настройка в одной кодировке, а данные в них — в другой.
-
Попробуйте начать с простого решения — того же запроса «Set Names», но в кодировке таблицы.
-
Для этого задайте запрос для названия вашей таблицы: show create table `table`
-
Используйте полученную кодировку в запросе «Set Names»:
SET NAMES кодировка
«кодировка» — это параметр, который показал результат запроса «Show Create Table» из пункта 3 (DEFAULT CHARSET=кодировка). -
Так вы уберёте «крякозябры» и знаки вопросов из MySQL, настроите правильную отдачу и запись русских букв в данных (главное, чтобы у самой веб-страницы была соответствующая кодировка), но проблему сортировки и поиска пока не решите. Идём дальше.
Теперь, зная кодировку таблицы (например, latin1) и имея данные в той же кодировке, мы должны изменить фактическую кодировку данных.
-
Через mysqldump создайте дамп базы данных.
-
Используйте эту команду, в которой вместо слова «кодировка» вставьте параметр, выясненный из кодировки таблицы:
mysqldump -uUSERNAME -pPASSWORD DB_NAME –allow-keywords –create-options –complete-insert –default-character-set=кодировка –add-drop-table > dump.sql -
Главное не перепутать кодировку таблиц с кодировкой данных.
-
Проверьте дамп на правильное отображение кодировки уже в формате данных таблицы, а не самой таблицы, как в пункте 3 (то есть уже не latin1, а utf8, например). Скопируйте бэкап дампа отдельно.
-
В дампе найдите оператор «Create Database» и проверьте, правильная ли в нём кодировка.
-
Если нет, то исправьте. Тоже самое можно (и лучше сделать) с оператором «Create Table».
-
Используйте эту команду для заливки дампа, где «кодировка» — параметр данных таблицы (utf8, а не latin1 из нашего примера):
mysql -uUSERNAME -pPASSWORD DB_NAME –default-character-set=utf8 < dump.sql -
На веб-странице сайта найдите функцию mysql_connect, затем mysql_select_db и ниже их размещения добавьте строчку, где «кодировка» — это параметр данных таблицы, а не самой таблицы:
mysql_query(“SET NAMES кодировка”)
Ничего не помогает, проблема кодировки MySQL так и осталась
Объёмный wiki-раздел по кодировке MySQL составили белорусские коллеги, где вы можете получить исчерпывающее описание процесса правильного создания баз данных и таблиц. Ведь именно в этом процессе кроются все причины возникновения проблемы со знаками вопросов MySQL и «крякозябрами» вместо русских букв.
Также обратите внимание и на эти моменты при работе с базами данных
- правильная ли задана кодировка при создании таблиц (можно использовать любую, но она должна отражать кодировку данных в таблице);
- правильная ли кодировка у скрипта, работающего с базой данных (кодировка веб-страницы и скрипта должна быть одной);
- правильная ли кодировка у самого сайта (у веб-страницы и заголовка «Content-Type» сайта она должна быть общая);
- в правильной ли кодировке сохраняются данные на веб-странице через редактор (выберите в редакторе нужную кодировку, следите за этим).
Компания ZEL-Услуги
Не хотите самостоятельно разбираться в настройке MySQL и оптимизировать работу ИТ-инфраструктуры предприятия? Передайте заботы о программном обеспечении в компанию ИТ-аутсорсинга с полноценным ИТ-аудитом и экспертной поддержкой по любым техническим вопросам и задачам.
Читайте также
- Где в России есть бесплатный интернет?
- Онлайн-касса бесплатно самозанятому: технология вопроса от айтишников
- IT-аутсорсинг в России: плюсы и минусы
- Технологии в бизнесе: 9 примеров, где ваши конкуренты обставят вас
- Мал бизнес, да удал: какие технологии сейчас помогают автоматизировать повторяющиеся задачи?
Может быть интересно
- Онлайн конструктор тарифов
- Цены и тарифы на ИТ-аутсорсинг
- Абонентское обслуживание компьютеров
- ИТ-директор
- Настройка и обслуживание серверов
Есть SQL запрос, который выполняется из скрипта python.
Проблема в том, что поле, которого нет в базе, выдает символы не utf8. Как это можно адекватно перекодировать в кириллицу? В самом питоновском скрипте или на стороне базы именно для этой переменной? Когда запрос выполняется на чистом sql, в базе все норм, отображается с кириллицей.
На питоне идет подключение к mssql через pymssql.
Вот запрос:
SELECT
CASE WHEN c_object_mane = '1' or c_object_mane = '2'
THEN 'Санкт-Петербург'
WHEN c_object_mane = '3'
THEN 'Москва'
END AS c_object_adress, an.[c_object_mane], an.[c_house_name], an.[c_type_room], an.[c_room], an.[c_status_flat], an.[lead_bujet], an.[c_an], an.[ddu_date]
FROM mssql_db as an where an.ddu_date >= '2021-01-01'
При выводе по логике должны нормально писать города Москва, Санкт-Петербург, но выходит только это:
Òþìåíü
Òþìåíü
Òþìåíü
Ìîñêâà
Òþìåíü
Òþìåíü
Òþìåíü
Òþìåíü
Òþìåíü
Mysql поддерживает много кодировок и это нередко является головной болью для программистов. Самая частая проблема — кракозяблы вместо русского текста. Это происходит из за того, что текст либо лежит на сервере, либо отдается клиенту в неверной кодировке. Последнее(а иногда и первое) решается проще всего. Устанавливаем кодировку соединения (в utf8 в примере) сразу после установления соединения
mysql_set_charset(‘utf8’); // или mysql_query(‘SET NAMES “utf8″‘); |
Хуже, когда скрипт отдает в базу, данные в верной кодировке, а в ответ получаем кракозяблы или вопросики. Или когда часть таблиц в верной кодировке, часть нет.. В таких случаях придется разбираться детально.
mysql_query(“SHOW VARIABLES LIKE ‘char%'” ); /* character_set_client: latin1 character_set_connection: latin1 character_set_database: utf8 character_set_filesystem: binary character_set_results: latin1 character_set_server: cp1251 character_set_system: utf8 character_sets_dir: usrlocalmysql-5.1sharecharsets */ |
Этот запрос обязательно проверять в самом скрипте, а не в phpmyadmin, где могут быть установлены другие параметры
character_set_client
— кодировка, в которой данные будут поступать от клиентаcharacter_set_connection
— по умолчанию для всего, что в рамках соединения не имеет кодировкиcharacter_set_database
— кодировка по умолчанию для базcharacter_set_filesystem
— кодировка для работы с файловой системой (LOAD DATA INFILE, SELECT … INTO OUTFILE, и т.д.)character_set_results
— кодировка, в которой будет выбран результатcharacter_set_server
— кодировка, в которой работает серверcharacter_set_system
— идентификаторы MySQL, всегда UTF8character_sets_dir
— папка с кодировками
По умолчанию после установки mysql сервер, который устанавливается ленивым хостеромадмином имеет кодировку latin1. Соответственно указанные выше глобальные переменные будут в latin1. Базы соответственно по умолчанию и таблицы так же. И именно на это стоит обратить в самом начале обратить внимание, чтобы проблемы не всплывали позднее.
В идеальном варианте, нам следуетпривести все отмеченные цветом кодировки к единому значению. Тогда мы просто будем избавлены от мелких ошибок с кодировкой. Фактически, если мы работаем с хостингом, то на (3) и (6) мы повлиять не сможем. Но и это не страшно если настроены остальные три параметра. Mysql умет перекодировать на лету если правильно настроена кодировка соединения.
Ну и наконец, основной вопрос, что делать если одна из mysql таблиц(или несколько) в неверной кодировке и на сайте видны кракозяблывопросики?
1. Выяснить кодировку таблицы.
mysql > SHOW CREATE TABLE `files` ————————————————————————— CREATE TABLE `files` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `iNode` int(10) unsigned NOT NULL, `pid` int(10) unsigned NOT NULL, `sName` varchar(128) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL, `sTitle` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, PRIMARY KEY (`id`), KEY `iNode` (`iNode`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
В этой таблице поле sName в кодировке latin1, если у нас соединение в другой кодировке, то мы увидим кракозябры.
2. Поэтому дальше проверим кодировку соединения, sql запросом SHOW VARIABLES LIKE ‘character_set_client’. Замечу, что php функция mysqli_client_encoding(), нам не подойдет, так как она отображает кодировку только на момент соединения.
3. Если кодировка соединения не совпала с кодировкой одного из полей таблицы, то 2 очевидных варианта.
Если у нас все таблицы в одной кодировке, то проще поменять кодировку соединения .
А как исправить неверную кодировку поля таблицы?
Для этого выполним 2 запроса
ALTER TABLE files CHANGE sName sName BLOB; ALTER TABLE files CHANGE sName sName VARCHAR(128) CHARACTER SET utf8; |
Нельзя обойтись только вторым запросом. Важно выполнить оба. Первый преобразовывает данные в двоичные, второй запрос, преобразовывает данные в строковые сменив кодировку.. Т.е. по сути мы не измениили двоичные данные, мы изменили правило формирования символов. Если бы мы попробовали обойтись только вторым запросом, то получили бы ошибочный набор.