СтатьиРабота MySQL со строкамиАвтор: Павел Пушкарев Начиная с версии 4.0, сервер MySQL поддерживает преобразование кодировок символов. Эта статья рассказывает о том, что такое кодировки, сопоставления и о том, как работать с ними применительно к серверу MySQL. Русскоязычные кодировкиТрадиционно в России использовались четыре кодировки для представления русских символов:
Эти четыре кодировки имеют как общие черты, так и различия. Во-первых, все они используют один байт информации для хранения одного символа. Во-вторых, они совместимы с кодировкой 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, о котором речь пойдет далее) используют не только кодировки, но и сопоставления символов. Дело в том, что некоторые символы некоторые языки считают одинаковыми (а иногда считаются одинаковыми символ или последовательность символов). Например, «u» в немецком языке может быть записан как «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). Хранение информации в MySQLMySQL хранит информацию в соответствии с тем, какую кодировку вы указали. Так сервер выделяет по 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 байт (впрочем, это не накладывает особых ограничений). |
||