Поиск в MYSQL для поля utf8_bin
Я создал таблицу и установил сопоставление в utf8, чтобы иметь возможность добавлять уникальный индекс в поле. Теперь мне нужно делать нечувствительные к регистру поисковые запросы, но когда я выполнил некоторые запросы с ключевым словом collate, я получил:
mysql> select * from page where pageTitle="Something" Collate utf8_general_ci;
ОШИБКА 1253 (42000): COLLATION 'utf8_general_ci' недействительна для CHARACTER SET 'latin1'
mysql> select * from page where pageTitle="Something" Collate latin1_general_ci;
ОШИБКА 1267 (HY000): Недопустимое сочетание сортировок (utf8_bin, IMPLICIT) и (latin1_general_ci, EXPLICIT) для операции '='
Я новичок в SQL, поэтому мне было интересно, сможет ли кто-нибудь помочь.
Ответы
Ответ 1
Строка в MySQL имеет набор символов и сопоставление. Utf8 - набор символов, а utf8_bin - одно из его сопоставлений. Чтобы сравнить строковый литерал с столбцом utf8, преобразуйте его в utf8, указав его на нотацию _charset:
_utf8 'Something'
Теперь сопоставление допустимо только для некоторых наборов символов. Сводка с учетом регистра для utf8 представляется utf8_bin, которую вы можете указать как:
_utf8 'Something' collate utf8_bin
При этих преобразованиях запрос должен работать:
select * from page where pageTitle = _utf8 'Something' collate utf8_bin
Префикс _charset работает со строковыми литералами. Чтобы изменить набор символов поля, существует CONVERT... USING. Это полезно, если вы хотите преобразовать поле pageTitle в другой набор символов, например:
select * from page
where convert(pageTitle using latin1) collate latin1_general_cs = 'Something'
Чтобы увидеть символ и сортировку для столбца с именем "col" в таблице с названием "TAB", попробуйте:
select distinct collation(col), charset(col) from TAB
Список всех наборов символов и сортировок можно найти с помощью:
show character set
show collation
И все допустимые сопоставления для utf8 можно найти с помощью:
show collation where charset = 'utf8'
Ответ 2
Также обратите внимание, что в случае использования "Collate utf8_general_ci" или "Collate latin1_general_ci", то есть "принудительного" сопоставления - такое преобразование предотвратит использование существующих индексов! Это может стать узким местом в будущем для производительности.
Ответ 3
Попробуйте это, его работа для меня
SELECT * FROM users
WHERE UPPER (name
) = UPPER ('josé') COLLATE utf8_bin;
Ответ 4
Могу ли я спросить, почему у вас есть необходимость явно изменить сортировку, когда вы выполняете SELECT? Почему бы просто не сопоставить то, как вы хотите получить записи при сортировке?
Проблема, с которой вы сталкиваетесь с вашими поисками, чувствительна к регистру, заключается в том, что у вас есть двоичная сортировка. Попробуйте вместо этого использовать общую сортировку. Для получения дополнительной информации о чувствительности к регистру и сопоставлениях см. Здесь:
Чувствительность к регистру при поиске строк