Что будет с существующими данными, если я изменю параметры сортировки столбца в MySQL? - PullRequest
7 голосов
/ 07 апреля 2011

Я запускаю производственное приложение с сервером базы данных MySQL.Я забыл установить параметры сортировки столбца от latin до utf8_unicode, что приводит к странным данным при сохранении в столбец с многоязычными данными.

У меня вопрос: что произойдет с моими существующими данными, если яизменить мое сопоставление на utf8_unicode сейчас?Будет ли он уничтожать или повреждать существующие данные или они останутся, но новые данные будут сохранены как utf8, как и должно быть?

Я изменю с помощью веб-клиента phpMyAdmin.

Ответы [ 5 ]

6 голосов
/ 07 апреля 2011

В статье http://mysqldump.azundris.com/archives/60-Handling-character-sets.html это подробно обсуждается, а также показано, что произойдет.

Обратите внимание, что вы смешиваете CHARACTER SET (фактически кодировку) с COLLATION.

Набор символов определяет физическое представление строки в байтах на диске.Вы можете сделать это видимым, используя функцию HEX (), например SELECT HEX(str) FROM t WHERE id = 1, чтобы увидеть, как MySQL хранит байты вашей строки.То, что MySQL предоставляет вам, может быть различным, в зависимости от набора символов вашего соединения, определенного с помощью SET NAMES .....

Сортировка - это порядок сортировки.Это зависит от набора символов.Например, ваши данные могут быть в наборе символов latin1, но они могут быть упорядочены в соответствии с одним из двух немецких порядков сортировки latin1_german1_ci или latin1_german2_ci.В зависимости от вашего выбора умлауты, такие как ö, будут сортироваться как oe или как o.

При изменении набора символов данные в вашей таблице необходимо переписать.MySQL прочитает все данные и все индексы в таблице, сделает скрытую копию таблицы, которая временно занимает место на диске, затем перемещает старую таблицу в скрытое место, перемещает скрытую таблицу на место и затем удаляет старые данные, освобождаяместо на диске.В течение некоторого промежутка времени вам потребуется в два раза больше места для этого.

При изменении параметров сортировки изменяется порядок сортировки данных, но не самих данных.Если столбец, который вы изменяете, не является частью индекса, ничего не нужно делать, кроме переписывания файла frm, и достаточно недавние версии MySQL не должны делать больше.

Когда вы изменяете параметры сортировки столбцаэто часть индекса, индекс необходимо переписать, так как индекс представляет собой отсортированный фрагмент таблицы.Это снова вызовет логику копирования таблицы ALTER TABLE, описанную выше.

MySQL пытается сохранить данные, выполняя это: Пока ваши данные могут быть представлены в целевом наборе символов, преобразование не будет с потерями.Предупреждения будут напечатаны, если происходит усечение данных, и данные, которые не могут быть представлены в целевом наборе символов, будут заменены на?

4 голосов
/ 07 апреля 2011

Запуск быстрого теста в MySQL 5.1 со столбцом VARCHAR, установленным на latin1_bin Я вставил несколько нелатинских символов

INSERT INTO Test VALUES ('英國華僑');

Я выбираю их и получаю мусор (как и ожидалось).

SELECT text from Test;

дает

text
????

Затем я изменил параметры сортировки столбца на utf8_unicode и повторно запустил SELECT, и он показал тот же результат

text
????

Эточто я ожидал - он сохранит данные, а данные останутся мусором, потому что, когда данные были вставлены, столбец потерял дополнительную символьную информацию и просто вставил?для каждого нелатинского символа и нет возможности для ????снова стать 英國 華僑.

Ваши данные останутся на месте, но не будут исправлены.

1 голос
/ 07 апреля 2011

Действительные данные будут правильно преобразованы:

Когда вы изменяете тип данных с помощью CHANGE или MODIFY, MySQL пытается преобразовать существующие значения столбца в новый тип, а такжевозможный.Предупреждение: это преобразование может привести к изменению данных.

http://dev.mysql.com/doc/refman/5.5/en/alter-table.html

... и более конкретно:

Чтобы преобразовать двоичный файл илистолбец недвоичных строк, чтобы использовать определенный набор символов, используйте ALTER TABLE.Для успешного преобразования необходимо выполнить одно из следующих условий: [...] Если столбец имеет недвоичный тип данных (CHAR, VARCHAR, TEXT), его содержимое должно быть закодировано в наборе символов столбца, а не в каком-либо другом символезадавать.Если содержимое закодировано в другом наборе символов, вы можете сначала преобразовать столбец в двоичный тип данных, а затем в недвоичный столбец с нужным набором символов.

http://dev.mysql.com/doc/refman/5.1/en/charset-conversion.html

Итак, ваша проблема в неверных данных, например, данных, закодированных в другом наборе символов.Я попробовал совет, предложенный в документации, и он в основном испортил мои данные, но причина в том, что мои данные уже были потеряны: запуск SELECT column, HEX(column) FROM table показал, что многобайтовые символы были вставлены как 0x3F (то есть, ?символ на латинице 1).Мой стек MySQL был достаточно умен, чтобы обнаружить, что входные данные не были Latin1 и преобразовать их во что-то «совместимое».И как только данные исчезнут, вы не сможете их вернуть.

Подводя итог:

  1. Используйте HEX (), чтобы выяснить, есть ли у вас еще данные.
  2. Сделайте свои тесты в копии таблицы.
0 голосов
/ 23 апреля 2017

ВНИМАНИЕ! Некоторые проблемы решаются с помощью

ALTER TABLE ... CONVERT TO ...

Некоторые решаются с помощью двухэтапного процесса

ALTER TABLE ... MODIFY ... VARBINARY...
ALTER TABLE ... MODIFY ... VARCHAR...

Если вы делаете неправильный, у вас будет худший беспорядок !

  1. Сделайте SELECT HEX(col), col ..., чтобы увидеть, что у вас есть на самом деле.
  2. Изучите это, чтобы увидеть, какой у вас случай: Проблема с символами utf8;я вижу не то, что сохранил
  3. Выполните правильное исправление, основываясь на следующих случаях: http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases
0 голосов
/ 11 мая 2015

Мой вопрос заключается в том, что произойдет с моими существующими данными, если я сейчас изменю свое сопоставление на utf8_unicode?

Ответ: Если вы измените на utf8_unicode_ci, с вашими существующими данными произойдет все, что угодно(который уже поврежден и остается поврежденным до тех пор, пока вы его не измените).

Будет ли он уничтожать или повреждать существующие данные или данные останутся, но новые данные будут сохранены в формате utf8, как и должно быть?

Ответ: После перехода к utf8_unicode_ci существующие данные не будут уничтожены.Он останется таким же, как и раньше (что-то вроде ????).Однако, если вы вставите новые данные, содержащие символы Юникода, они будут сохранены правильно.

Я изменю с помощью веб-клиента phpMyAdmin.

Ответ: Конечно, вы можете изменитьсопоставление с phpMyAdmin. Для этого выберите «Операции»> «Параметры таблицы»

.
...