какую сортировку mysql utf8 использовать для данных, поступающих из latin1 - PullRequest
1 голос
/ 24 июня 2011

У меня много данных в mysql в формате latin1, и я пытаюсь преобразовать все в utf8, но до сих пор я не нашел правильного сопоставления для правильного преобразования. Некоторые из данных являются международными именами с большим акцентом, символами из разных языков и первичным ключом в этих полях. У меня есть простой тестовый пример, который выглядит так:

CREATE TABLE utf8_test ( value varchar(30), PRIMARY KEY(value) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci;
INSERT INTO utf8_test VALUES ('e');
INSERT INTO utf8_test VALUES ('é');
INSERT INTO utf8_test VALUES ('è');
INSERT INTO utf8_test VALUES ('ü');
INSERT INTO utf8_test VALUES ('u');
INSERT INTO utf8_test VALUES ('y');
INSERT INTO utf8_test VALUES ('ÿ');

Это простой тест для демонстрации проблемы, но реальные данные этим не ограничиваются.

Пока что только utf8_bin может принимать все без повторяющихся ошибок, но я не могу его использовать, потому что он чувствителен к регистру. Я что-то упустил?

примечание: в некоторых таблицах более десятка миллионов строк, поэтому производительность является фактором.

Ответы [ 2 ]

1 голос
/ 24 июня 2011

Насколько я знаю, в MySQL пока нет сортировки utf8 с учетом регистра, поэтому utf8_bin - ваш единственный выбор. utf8_bin чувствителен к регистру и обрабатывает все диакритические знаки как отдельные. Как отметила Блэр Конрад, это может привести к беспорядку сортировки. Возможно, вам удастся решить эту проблему с помощью , используя collate в ваших операторах SQL , хотя, если у вас много операторов SQL, такой подход может быть проблематичным.

CREATE TABLE `utf8_test` (
  `value` varchar(30) COLLATE utf8_bin NOT NULL DEFAULT '',
  PRIMARY KEY (`value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

INSERT INTO utf8_test VALUES ('e');
INSERT INTO utf8_test VALUES ('é');
INSERT INTO utf8_test VALUES ('è');
INSERT INTO utf8_test VALUES ('ü');
INSERT INTO utf8_test VALUES ('u');
INSERT INTO utf8_test VALUES ('y');
INSERT INTO utf8_test VALUES ('ÿ');

INSERT INTO utf8_test VALUES ('E');
INSERT INTO utf8_test VALUES ('É');
INSERT INTO utf8_test VALUES ('È');
INSERT INTO utf8_test VALUES ('Ü');
INSERT INTO utf8_test VALUES ('U');
INSERT INTO utf8_test VALUES ('Y');
INSERT INTO utf8_test VALUES ('Ÿ');

SELECT value FROM utf8_test WHERE value = 'E';
+-------+
| value |
+-------+
| E     |
+-------+

SELECT value FROM utf8_test WHERE value COLLATE utf8_unicode_ci = 'E';

+-------+
| value |
+-------+
| E     |
| e     |
| È     |
| É     |
| è     |
| é     |
+-------+

SELECT value FROM utf8_test ORDER BY value;

+-------+
| value |
+-------+
| E     |
| U     |
| Y     |
| e     |
| u     |
| y     |
| È     |
| É     |
| Ü     |
| è     |
| é     |
| ü     |
| ÿ     |
| Ÿ     |
+-------+

SELECT value FROM utf8_test ORDER BY value COLLATE utf8_unicode_ci;

+-------+
| value |
+-------+
| E     |
| é     |
| è     |
| É     |
| È     |
| e     |
| u     |
| Ü     |
| U     |
| ü     |
| y     |
| Y     |
| ÿ     |
| Ÿ     |
+-------+
1 голос
/ 24 июня 2011

Правильная сортировка зависит не только от исходного набора символов (Latin-1). Это зависит от языка и локали, из которой получены данные. Если вы просто беспокоитесь о том, чтобы ни один символ не складывался один в другой, возможно, вам подойдет utf8_bin.

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

Чтобы получить регистр без учета регистра, вы можете попробовать utf8_general_ci или utf8_unicode_ci, как описано в UTF-8: General? Бен? Unicode

Редактировать Дальнейшие исследования показывают, что в настоящее время нет сопоставления, которое вы можете использовать. См http://bugs.mysql.com/bug.php?id=19567.

Как это для варианта? Назначьте utf8_bin для ваших столбцов, но примените к вашим запросам другой порядок сортировки (тот, который будет складывать регистр и акценты)? Вы не потеряете данные, и ваши запросы будут без учета регистра. Если не чувствительные к акценту запросы не причинят вам вреда, это может быть компромиссом ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...