Преобразование таблиц mysql с latin1 в utf8
Я пытаюсь преобразовать некоторые таблицы mysql из latin1 в utf8. Я использую следующую команду, которая, похоже, работает в основном.
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
Однако на одной таблице я получаю сообщение об ошибке с дублирующимся ключом. Это вызвано уникальным индексом в поле "имя". Кажется, что при преобразовании в utf8 любые "специальные" символы индексируются как их прямой английский эквивалент. Например, уже есть запись с именем поля "Dru". При преобразовании в utf8 запись с "Дру" считается дубликатом. То же самое с "Патриком" и "Påtrìçk".
Вот как воспроизвести проблему:
CREATE TABLE `example` ( `name` char(20) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`name`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO example (name) VALUES ('Drü'),('Dru'),('Patrick'),('Påtrìçk');
ALTER TABLE example convert to character set utf8 collate utf8_general_ci;
ERROR 1062 (23000): Duplicate entry 'Dru' for key 1
Ответы
Ответ 1
Причина, по которой строки 'Drü'
и 'Dru'
оценивают как то же самое, что в сортировке utf8_general_ci
они считаются "одинаковыми". Цель сортировки для набора символов заключается в предоставлении набора правил относительно того, когда строки одинаковы, когда один сортируется перед другим и т.д.
Если вам нужен другой набор правил сравнения, вам нужно выбрать другую сортировку. Вы можете увидеть доступные сопоставления для набора символов utf8
, выпустив SHOW COLLATION LIKE 'utf8%'
. Есть куча сопоставлений, предназначенных для текста, который в основном используется на определенном языке; существует также сопоставление utf8_bin
, которое сравнивает все строки как двоичные строки (т.е. сравнивает их как последовательности из 0s и 1s).
Ответ 2
UTF8_GENERAL_CI
нечувствителен к акценту.
Используйте UTF8_BIN
или специфическую для языка сортировку.