Просто о кодировке MySQL. Как избежать всех ошибок.

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

Для начала объясним основные понятия вообще:

Что такое кодировка (character set):
Допустим, у нас есть символы «А», «Б», «а», «б». Мы присвоим каждому символу определенный код: «А» = 0, «Б» = 1, «а» = 2, «б» = 3.
Т.е. «А» — символ, 0 – код.
Таким образом комбинация всех символов и соответствующих им кодов называется кодировкой.

Например, «А» в кодировке cp1251 = xC0 , а в UTF8 = xD090

Что такое сравнение (collation):
Допустим нам нужно сравнить символы «А», «Б».
В простейшем случае, нам нужно взять их коды и сравнить сами коды. Т.е. если: «А» = 0, «Б» = 1 и 0 < 1 соответственно «А» < «Б». То, что мы сделали и называется сравнением (collation). Этот простейший метод сравнения, по кодам, называется бинарным (binary).

А что если нам необходимо считать маленькие и большие буквы равнозначными («А» = «а»). И так сравнить слова состоящие из символов? Для этого нам нужно использовать другой метод сравнения регистронезависимый (case-insensitive).

Вот для чего нам нужно выбирать в mysql нужный collation.

Касательно кодировок в MySQL

MySQL используется для:

  1. хранения данных в определенной кодировке (задается — character_set_database)
  2. сравнения хранимых данных различными способами (collation) (collation_database)
  3. выдачи пользователю данных в требуемой ему кодировке (character_set_results), а не только в хранимой.
  4. получения от пользователя данные в различных кодировках и конвертации в кодировку БД. (character_set_client)

Подробнее о кодировках уже рассказывал тут: настройки кодировок.

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

  • для всего mysql сервера
    (параметры: character_set_server, collation_server),
  • для отдельной БД
    (параметры: character_set_database, collation_database),
  • для текущего соединения с БД
    (параметры: character_set_client, character_set_connection, character_set_results
    Или запросы:

    SET CHARACTER SET utf8
    SET NAMES utf8

    ),

  • для отдельной таблицы
    (запрос при создании таблицы:

    CREATE TABLE `users` (
    `id` int(11) unsigned NOT NULL auto_increment,
    `login` varchar(255) NOT NULL,
    ...
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;

    ),

  • Для отдельного поля
    (Запрос

    ALTER TABLE `tableName` 
    CHANGE `поле` `поле` TINYTEXT 
    CHARACTER SET cp1251 
    COLLATE cp1251_general_ci NOT NULL
    

    ),

  • для отдельного запроса
    (Запрос:

    SELECT нужные поля 
    FROM TableName 
    ORDER BY поле1 
    COLLATION utf8_general_ci
    

    ).

Таким образом ошибки возникают:
— когда данные хранятся в одной, но указано, что другая кодировка;
— неверно указан метод сравнения — ошибки в сортировке;
— вы пытаетесь получить данные в кодировке по умолчанию, а не той, которой вам нужна.

Разобравшись теперь с этой статьей у вас больше не возникнет ошибок с неверной кодировкой или сортировкой в MySQL.

Официальный мануал:
http://dev.mysql.com/doc/refman/5.0/en/charset.html

PS: Однажды у меня возникли проблемы с сортировкой. Сначала думал в сторону кодировки, потом оказалось, что данная ошибка из-за параметра max_sort_length (количество сортируемых символов) Запрос: SELECT @@max_sort_length;

Просто о кодировке MySQL. Как избежать всех ошибок.: 3 комментария

Добавить комментарий

Ваш адрес email не будет опубликован.