| Работа MySQL со строкамиДата: 21.01.2007 Автор: Павел Пушкарев  , paulus (at) sqlinfo (dot) ru 
        Начиная с версии 4.0, сервер MySQL поддерживает преобразование кодировок
        символов. Эта статья рассказывает о том, что такое кодировки, сопоставления
        и о том, как работать с ними применительно к серверу MySQL.
         Русскоязычные кодировки
        Традиционно в России использовались четыре кодировки для представления
        русских символов:
         
                CP866 (DOS)KOI8-RMacCyrillicCP1251 (Windows) 
        Эти четыре кодировки имеют как общие черты, так и различия. Во-первых, все
        они используют один байт информации для хранения одного символа. Во-вторых,
        они совместимы с кодировкой latin1, т.е. у них совпадают первые 128 байт
        таблицы кодировки. Различаются же значения символов с установленным верхним
        битом (т.е. со значениями 128-255).
         
        Даже четыре кодировки символов для одного языка — это очень много.
        Изначально люди не придавали этому значения, но в последние несколько лет
        это стало не так. Возникли разнообразные проблемы переносимости программ, и
        люди решили создать обобщающие кодировки, содержащие символы всех языков мира
        (в том числе, разумеется, и русского).
         
        Так была создана кодировка Unicode (UCS-2). Разумеется, невозможно разместить
        очень большое количество символов в 8 битах, поэтому в этой кодировке
        используются 2 байта (т.е. 16 бит) на каждый символ. Строки в этой кодировке, безусловно,
        занимают больше места, чем в старых кодировках, но зато приложения, использующие
        такие строки, очень легко переносятся на другие языки.
         
        Не смотря на введение UCS-2, некоторые проблемы все-же остались. Во-первых, это
        уже указанное увеличение длины строки. Люди, использующие только латинские символы,
        не могли для себя понять, почему они должны использовать 16 бит для обозначения
        символов, которые уместятся в 7 бит. Во-вторых, 65536 символов все равно не хватает
        для обозначения всех используемых символов на планете.
         
        Для преодоления этих трудностей, была создана кодировка с переменной длиной символа
        UTF-8. В этой кодировке используется 1 байт для обозначения первых 128 символов
        (т.е. символов, входящих в latin1). Если установлен верхний бит первого байта, то
        используется второй байт (т.е. русские буквы в этой кодировке занимают 2 байта).
        Если установлен верхний бит второго байта, то используется третий байт (и туда входят
        разнообразные иероглифы и другие восточные символы) и так далее.
         
        Такая кодировка во-первых, может разместить в себе произвольное количество
        символов (т.к. она позволяет увеличивать количество байт динамическим
        образом). Во-вторых, для английского языка используется 1 байт, и это очень
        приятно для англоговорящих стран. Восточные страны не очень любят эту кодировку,
        т.к. им приходится использовать 3 байта для обозначения своих символов (в UCS-2
        они используют только два).
         Сопоставления символов
        Некоторые приложения (включая и MySQL, о котором речь пойдет далее) используют
        не только кодировки, но и сопоставления символов. Дело в том, что некоторые
        символы некоторые языки считают одинаковыми (а иногда считаются одинаковыми
        символ или последовательность символов). Например, «ü» в немецком
        языке может быть записан как «ue». С другой стороны, в шведском языке
        тот же символ может быть записан как «uy».
         
        В русском языке можно, например, считать одинаковыми буквы «е» и
        «ё» (как часто делают в официальных документах). Также часто
        бывает полезным не различать большие и маленькие буквы (которые имеют разный
        код в любой кодировке).
         
        Сопоставление влияет именно на то, как приложение работает с совокупностью
        символов, оно влияет на порядок сортировки и на сравнение символов. Разумеется,
        сопоставление зависит от кодировки символов.
         Кодировки символов в MySQL
        В сервере MySQL у каждой строки есть своя кодировка и сопоставление.
        При создании таблицы, Вы можете указать кодировку и сопоставление, в которых
        будут сохранены строки внутри таблицы. Вы можете даже указывать эти параметры
        для каждого поля таблицы. Например:
         
        CREATE TABLE enctest (str1 CHAR(10) CHARSET koi8r,
 str2 CHAR(15) COLLATE utf8_general_ci
 );
 
        В данном примере создается таблица с двумя полями, одно из которых будет
        храниться в кодировке KOI8-R (и с сопоставлением по-умолчанию). Второе поле
        будет иметь сопоставление utf8_general_ci и кодировку UTF-8 (кодировка определяется
        по сопоставлению, т.к. сопоставление зависит от нее).
         
        Список доступных кодировок и сопоставлений Вы можете получить, соответственно,
        командами
         
        SHOW CHARACTER SET;SHOW COLLATION;
 Кодировки по умолчанию и смена кодировки строк в MySQL
        Если Вы не хотите явно указывать кодировку строк в таблице, Вы можете для
        этой таблицы указать кодировку символов по-умолчанию:
         
        CREATE TABLE enctest2 (str1 CHAR(10),
 str2 CHAR(15)
 ) DEFAULT CHARSET cp1251;
 
        В данном случае, обе строки будут созданы в кодировке CP1251. Вы можете
        указывать кодировки отдельных строк и в случае указания кодировки по-умолчанию.
         
        Вы также можете изменить кодировку символов для конкретного поля таблицы:
         
        ALTER TABLE enctest2 MODIFY str1 CHAR(10) CHARSET utf8;
         
        В данном случае, в поле str1 изменяется кодировка и все строки перекодируются.
        Учтите, что если Вы изменяете кодировку по-умолчанию для таблицы, то строки
        в ней не перекодируются, Вы просто влияете на создание других полей в этой
        таблице.
         Сопоставления в MySQL
        В MySQL для каждой кодировки есть по крайней мере одно сопоставление (а обычно,
        несколько). Для того, чтобы понять, чем они отличаются, они все имеют очень
        подробные названия.
         
        Название каждого сопоставления начинается с названия соответствующей кодировки
        (например, utf8_). Далее идет спецификация сопоставления (чаще всего, идет
        простое сопоставление, general, не идентифицирующее буквы) и указание на
        чувствительность к регистру (cs — case sensitive — чувствительно
        к регистру, ci — case insensitive — не чувствительно).
         
        Отдельно стоит отметить бинарные сопоставления (binary). Если строки 
        сопоставляются бинарным
        образом, то между ними не делается никаких сопоставлений и преобразований.
        Такие строки не будут преобразованы командой SET NAMES (см. далее).
        Бинарные сопоставления особенно удобно использовать при переходе с
        MySQL 3.23, который не поддерживал кодировки и который указывает, что все
        таблицы находятся в кодировке latin1 (не смотря на то, что таблицы могут
        содержать данные, скажем, в KOI8-R).
         Клиентские кодировки MySQL
        Сервер MySQL автоматически изменяет кодировку строк при занесении данных в
        таблицу и при выборке данных из таблицы. При этом он использует данные из
        системных переменных, таких, как character_set_client. Список всех переменных,
        влияющих на кодировки, Вы можете получить, выполнив команду
         
        SHOW VARIABLES LIKE 'char%';
         
        Вы можете указывать или переменные по-одиночке, или изменять их сразу
        большим набором (как требуется в большинстве случаев):
         
        SET NAMES koi8r;
         
        После того, как сервер получит такую команду, он будет ожидать, что Вы будете
        передавать ему все строки в кодировке KOI8-R и будет автоматически переводить
        выводимые им строки в эту кодировку.
         
        Это удобно тогда, когда сервер по-умолчанию работает не в той кодировке,
        которую Вы ожидаете (например, в KOI8-R, а Вы хотите выводить информацию на
        сайте в CP1251).
         Хранение информации в MySQL
        MySQL хранит информацию в соответствии с тем, какую кодировку вы указали.
        Так сервер выделяет по 1 байту на каждый символ для однобайтовых кодировок
        (при этом CHAR(10) занимает всегда 10 байт, VARCHAR(10) занимает от 1 до
        11 байт в зависимости от длины строки, 1 лишний байт тратится на хранение
        длины строки).
         
        Для кодировки UCS-2 сервер выделяет по 2 байта на каждый
        символ. Для кодировки UTF-8 сервер выделяет разное количество байт для
        разных символов (в соответствии с кодировкой) в случае VARCHAR и 3 байта
        на каждый символ в случае CHAR. Таким образом, в UTF-8 строка CHAR(10) 
        всегда занимает 30 байт, а VARCHAR(10)
        — от 1 до 31 байта.При этом ни в каком случае при применении
        UTF-8 сервер не может хранить символы длиной от 4 байт (впрочем, это
        не накладывает особых ограничений).
         Дата публикации: 21.01.2007 
 © Все права на данную статью принадлежат порталу SQLInfo.ru. Перепечатка в интернет-изданиях разрешается только с указанием автора и прямой ссылки на оригинальную статью. Перепечатка в бумажных изданиях допускается только с разрешения редакции. |