MySQL с учетом регистра запросов
Это задано на этом сайте раньше, но я не смог найти достаточного ответа. Если я делаю запрос вроде:
Select Seller from Table where Location = 'San Jose'
Как я могу заставить его возвращать только продавцов с местоположением "Сан-Хосе" вместо "san jose" или что-то еще?
Ответы
Ответ 1
По умолчанию запросы MySQL не чувствительны к регистру. Ниже приведен простой запрос, который ищет "значение". Однако он вернет "VALUE", "значение", "VaLuE" и т.д.
SELECT * FROM `table` WHERE `column` = 'value'
Хорошей новостью является то, что если вам нужно сделать запрос с учетом регистра, это очень легко сделать с помощью оператора BINARY
, который заставляет сравнивать байты по байтам:
SELECT * FROM `table` WHERE BINARY `column` = 'value'
Ответ 2
Чтобы улучшить превосходный ответ Джеймса:
Лучше поставить BINARY
вместо константы:
SELECT * FROM `table` WHERE `column` = BINARY 'value'
Помещение BINARY
перед column
будет препятствовать использованию любого индекса в этом столбце.
Ответ 3
В то время как указанный ответ верен, могу ли я предположить, что если в вашем столбце будут храниться строки, чувствительные к регистру, вы будете читать документацию и изменить свою таблицу соответственно.
В моем случае это означало определение моей колонки как:
`tag` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''
Это, на мой взгляд, предпочтительнее корректировать ваши запросы.
Ответ 4
Самый правильный способ выполнить сравнение строк с учетом регистра без изменения параметров сортировки запрашиваемого столбца - это явно указать набор символов и параметры сопоставления для значения, с которым сравнивается столбец.
select Seller from Table where Location = convert('San Jose' using utf8mb4) collate utf8mb4_bin;
Почему бы не использовать BINARY
?
Использование оператора BINARY
нецелесообразно, поскольку он сравнивает фактические байты кодированных строк. Если вы сравните фактические байты двух строк, закодированных с использованием разных наборов символов, две строки, которые следует считать одинаковыми, могут быть не равны. Например, если у вас есть столбец, который использует набор символов latin1
, а ваш набор символов сервера/сеанса имеет значение utf8mb4
, то при сравнении столбца со строкой, содержащей акцент, такой как 'café', он не будет совпадать со строками, содержащими эту же строку ! Это связано с тем, что в latin1
кодируется как байт 0xE9
а в utf8
это два байта: 0xC3A9
.
Зачем использовать convert
а также collate
?
Сопоставления должны соответствовать набору символов. Поэтому, если ваш сервер или сеанс настроен на использование набора символов latin1
вы должны использовать collate latin1_bin
но если ваш набор символов - utf8mb4
вы должны использовать collate utf8mb4_bin
. Поэтому наиболее надежное решение - всегда преобразовывать значение в наиболее гибкий набор символов и использовать двоичное сопоставление для этого набора символов.
Зачем применять convert
и collate
для значения, а не столбца?
Когда вы применяете любую функцию преобразования к столбцу перед выполнением сравнения, он не позволяет обработчику запросов использовать индекс, если он существует для столбца, что может значительно замедлить ваш запрос. Поэтому всегда лучше преобразовывать значение, где это возможно. Когда сравнение выполняется между двумя строковыми значениями, и одно из них имеет явно заданное сопоставление, механизм запросов будет использовать явное сопоставление независимо от того, к какому значению оно применяется.
Акцент Чувствительность
Важно отметить, что MySql не только нечувствителен к регистру столбцов, использующих _ci
сортировки _ci
(как правило, по умолчанию), но также нечувствителен к акценту. Это означает, что 'é' = 'e'
. Использование двоичного сопоставления (или binary
оператора) сделает сравнения строк чувствительными к акценту, а также к регистру.
Что такое utf8mb4
?
Набор символов utf8
в MySql - это псевдоним utf8mb3
который в последних версиях устарел, поскольку он не поддерживает 4-байтовые символы (что важно для кодирования строк типа 🐈). Если вы хотите использовать кодировку символов UTF8 с MySql, вам следует использовать кодировку utf8mb4
.