Расшифровка MySQL Encoding - PullRequest
       29

Расшифровка MySQL Encoding

1 голос
/ 29 ноября 2011

У меня проблема с кодировкой в ​​MySQL, и мне нужна помощь в выяснении того, что происходит.

Сначала несколько параметров. Кодировка таблицы по умолчанию - utf8. Тем не менее, все системные переменные MySQL - character_set_client, character_set_connection, collation_connection и character_set_server - являются латинскими.

Я захожу на свой сервер MySQL и подключаюсь к локальному серверу с помощью локального клиента командной строки. Я выбираю запись / столбец и возвращаемую строку, скажем, символ возвращается как A, и это правильно. A обозначается шестнадцатеричным в UTF-8 как «C5 9F».

Однако приложение PHP, которое подключается к серверу, интерпретирует его как XY. В клиенте командной строки MySQL, если я отправлю команду «SET NAMES utf8», он также теперь будет отображаться как XY.

Если я выбираю INTO OUTFILE и использую hexedit для редактирования файла, я вижу два шестнадцатеричных символа, которые отображаются на X, затем два шестнадцатеричных символа, которые отображаются на Y. ("c3 85" для X и "C5 B8" для Y). По сути, он принимает два шестнадцатеричных значения и отображает их действительно как символы UTF8.

Прежде всего, похоже, что база данных действительно хранит вещи как UTF8, но неправильный тип UTF8, верно? Они входят как сырой Unicode, но каким-то образом, возможно, из-за переменных системы, это не переводится в UTF8?

Во-вторых, как / почему клиент командной строки MySQL правильно интерпретирует XY как A?

Наконец, к успешной интерпретации командной строки MySQL, есть ли диаграмма, которая показывает, как C3 85 C5 B8 преобразуется в A, или XY преобразуется в A?

Спасибо большое за понимание.

1 Ответ

2 голосов
/ 29 ноября 2011

Ваш вопрос несколько сбивает с толку, поэтому я объясню на моем собственном примере:

Вы подключаетесь к базе данных без выдачи SET NAMES, поэтому соединение установлено на Latin-1.Это означает, что база данных ожидает любого обмена данными между вами и ее кодированием на латинице-1.
Вы отправляете байты C3A2 в базу данных, которую вы хотите обозначить "â" в UTFКодировка -8.
База данных, ожидающая Latin-1, интерпретирует это как символы "Â" (C3 и A2 в кодировке Latin-1).
База данных будет хранить эти дваВнутренние символы в любой кодировке таблицы установлены на.

Вы подключаетесь к базе данных другим способом, выполняя SET NAMES UTF-8.Теперь база данных ожидает с вами общения в UTF-8.
Вы запрашиваете данные, хранящиеся в базе данных, вы получаете символы "Â", закодированные в UTF-8, как C382 C2A2, потому что вы сказали базе данных хранить символов"Â", и теперь вы запрашиваете их через соединение UTF-8.

Если вы снова подключитесь к базе данных, используя для подключения Latin-1, база данных выдастВы символы "¢", закодированные в Latin-1, которые являются байтами C3 A2.Если клиент, который вы использовали для подключения, интерпретирует это в Latin-1, вы увидите символы «¢».Если клиент интерпретирует это как UTF-8, вы увидите символ «â».

По сути, это точки, в которых что-то может испортить:

  • база данныхинтерпретирует любые байты , которые он получает, как символы в любой кодировке, установленной для соединения, и преобразует кодировку этих символов в таблицу, в которой они должны храниться в
  • база данных преобразует кодировку любых символов из кодировки, в которой они хранятся, в кодировку соединения при извлечении данных
  • клиент может интерпретировать или не интерпретировать байт он получает из базы данных правильные символы для отображения на экране, особенно в средах командной строки не всегда настроено правильное отображение данных UTF-8

Надеюсь, это поможет.

...