MySQL без учета регистра выбора


242

Может кто-нибудь сказать мне, если SELECTзапрос MySQL чувствителен к регистру или регистронезависимый по умолчанию? И если нет, то какой запрос я должен отправить, чтобы я мог сделать что-то вроде:

SELECT * FROM `table` WHERE `Value` = "iaresavage"

Где в действительности, реальная ценность Valueесть IAreSavage.


44
В конечном счете, это зависит от полевого сопоставления - если это '_ci' (без учета регистра) или '_cs' (с учетом регистра)
Jovan Perovic

15
Это один плохо сформулированный вопрос;). Половина ответов показывает, как проводить сравнение без учета регистра, половина - с учетом регистра. И только 1 говорит вам, что по умолчанию регистр не учитывается. :) Стоит отметить, что нечувствительность к регистру работает, даже когда вы делаете сравнение, как'value' in ('val1', 'val2', 'val3')
SaltyNuts

5
@SaltyNuts человек, читая этот вопрос 7 лет спустя и понимая, насколько я нуб, я смущаюсь! Я мог бы просто прочитать документацию, и ответ, как в первом предложении об операторах SELECT ...
NoodleOfDeath,

Чтобы добавить к тому, что сказал @JovanPerovic, utf8_bin также делает его чувствительным к регистру. Не уверен, существовало ли это тогда
Chiwda

Ответы:


494

Они нечувствительны к регистру , если вы не делаете двоичное сравнение .


3
Я в основном согласен с комментарием Тима, я не думаю, что выполнение «lower ()» для ваших значений везде - лучший способ справиться с этим, кажется обходным решением. Но я признаю, что иногда это имеет смысл и проще. (Колин упомянул, что сортировка была лучше). Мы перенесли исторические данные в таблицу mysql, что нарушило устаревшую логику из-за того, что некоторые значения столбцов имели нечувствительный регистр. Нам нужно было знать разницу между «GE1234» и «ge1234», они должны были быть уникальными и оставаться зарегистрированными таким образом. Вместо этого мы устанавливаем наш столбец в операторе создания таблицы следующим образом: varchar (20) CHARACTER SET utf8 COLLATE utf8_bin
gregthegeek

19
Я не знаю, почему так много людей проголосовали за это. Здесь четко сказано dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html, что «... это означает, что для буквенных символов сравнения будут чувствительными к регистру». Так что, если я найду «DickSavagewood», он НЕ подберет «Dicksavagewood». То же самое с LOWER () подхватит его. Итак, мой ответ на вопрос: в вашем конкретном случае SELECT действительно чувствителен к регистру.
Люфтваффле

10
@ user1961753: Прочитайте еще раз: «Для двоичных строк (varbinary, blob) ... будет учитываться регистр».
Марк Б

1
@MarcB эта ссылка теперь не работает. Не могли бы вы это исправить? :)
Phiter

5
Как сказал Йован, это зависит от сопоставления, поэтому этот ответ в значительной степени неверен.
phil294

117

Вы можете в нижнем регистре значение и переданный параметр:

SELECT * FROM `table` WHERE LOWER(`Value`) = LOWER("IAreSavage")

Другой (лучший) способ - использовать COLLATEоператора, как сказано в документации.


21
Как бы это SELECTутверждение выглядело COLLATEтогда?
Да, Барри

11
На упомянутой выше странице документации говорится, что «недвоичные сравнения строк по умолчанию не чувствительны к регистру».
Пер Квестед Аронссон

9
Как-то страшно, сколько людей проголосовало за этот ответ. Как объясняет @Marc выше, сравнения не чувствительны к регистру. Вы должны понимать параметры сортировки и индексы и правильно их настраивать - использование строковых преобразований, таких как LOWER()или произвольное COLLATEпредложение, может полностью обойти индекс, и со временем, по мере роста вашей таблицы, это может иметь радикальные последствия для производительности. Вероятно, это имена пользователей, которые вы ищете? Используйте сортировку без учета регистра и добавьте уникальный индекс в столбец. Используйте, EXPLAINчтобы подтвердить, что индекс используется.
mindplay.dk

1
Я собирался сказать то же самое, что mindplay.dk ... upper () и lower () обходят индекс и напрямую влияют на производительность больших таблиц базы данных.
Г.Т.Доров

Я согласен с мнением mindplay.dk и GTodorov. Будьте осторожны, используя какой-либо метод для целевого столбца в предложении where. Индекс столбца может быть бесполезным. Используйте EXPLAIN!
Traeper

51

ИСПОЛЬЗОВАТЬ BINARY

Это простой выбор

SELECT * FROM myTable WHERE 'something' = 'Something'

= 1

Это выбор с двоичным

SELECT * FROM myTable WHERE BINARY 'something' = 'Something'

или

SELECT * FROM myTable WHERE 'something' = BINARY 'Something'

= 0


3
Когда имеет смысл использовать BINARY только с одной стороны от = (SELECT * FROM myTable WHERE BINARY 'some' = 'Something')?
Джимми

@ Джимми Что ты имеешь в виду? Код работает. Когда одна сторона в сравнении преобразуется в двоичную, сравнение выполняется в двоичной форме.
Джори

@Jori О, я думаю, что я неправильно прочитал - я думал, что на одном из двух примеров был BINARY с обеих сторон.
Джимми

Я только что проголосовал за это, потому что это действительно правильный ответ. Согласно документации на веб-сайте MySQL, они говорят, что лучше использовать команду BINARY, чем пытаться перевести ваши слова / запросы на конкретный язык, потому что команда BINARY говорит, что нужно оставить все как есть и использовать его точно так же, как это представлено. Поэтому, когда я пришел в поисках ответа - два ответа привели меня на веб-сайт MySQL и посмотрели их документацию. Использование BINARY лучше. Перевод может вызвать другие проблемы.
Марк Мэннинг

43

Сравнения нечувствительны к регистру, когда столбец использует параметры сортировки, которые заканчиваются на _ci(например, параметры latin1_general_ci сортировки по умолчанию ), и они чувствительны к регистру, когда столбец использует параметры сортировки, которые заканчиваются на _csили _bin(такие как utf8_unicode_csиutf8_bin сортировки).

Проверьте сопоставление

Вы можете проверить параметры сортировки вашего сервера , базы данных и соединений, используя:

mysql> show variables like '%collation%';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | utf8_general_ci   |
| collation_database   | latin1_swedish_ci |
| collation_server     | latin1_swedish_ci |
+----------------------+-------------------+

и вы можете проверить свою таблицу сортировки с помощью:

mysql> SELECT table_schema, table_name, table_collation 
       FROM information_schema.tables WHERE table_name = `mytable`;
+----------------------+------------+-------------------+
| table_schema         | table_name | table_collation   |
+----------------------+------------+-------------------+
| myschema             | mytable    | latin1_swedish_ci |

Изменить параметры сортировки

Вы можете изменить параметры сортировки базы данных, таблицы или столбца на следующие с учетом регистра:

-- Change database collation
ALTER DATABASE `databasename` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;

-- or change table collation
ALTER TABLE `table` CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;

-- or change column collation
ALTER TABLE `table` CHANGE `Value` 
    `Value` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin;

Ваши сравнения должны теперь быть чувствительными к регистру.


25

Сравнение строк в фразе WHERE не чувствительно к регистру. Вы можете попробовать сравнить, используя

WHERE `colname` = 'keyword'

или

WHERE `colname` = 'KeyWord'

и вы получите же результат . Это поведение по умолчанию MySQL.

Если вы хотите, чтобы сравнение было чувствительным к регистру , вы можете добавитьCOLLATE вот так:

WHERE `colname` COLLATE latin1_general_cs = 'KeyWord'

Этот SQL даст другой результат с этим: ГДЕ colname COLLATE latin1_general_cs = 'ключевое слово'

latin1_general_cs в большинстве баз данных является обычной или стандартной сортировкой.


16

Выбранная вами сортировка устанавливает, чувствительны ли вы к регистру или нет.


9

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

Сценарий ниже создает таблицу. Обратите внимание, внизу написано «COLLATE latin1_general_cs». Это cs в конце означает регистр символов. Если вы хотите, чтобы ваша таблица не учитывала регистр символов, вы должны либо пропустить эту часть, либо использовать «COLLATE latin1_general_ci».

   CREATE Table PEOPLE (

       USER_ID  INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,

       FIRST_NAME  VARCHAR(50) NOT NULL,
       LAST_NAME  VARCHAR(50) NOT NULL,

       PRIMARY KEY (USER_ID)

   )

   ENGINE=MyISAM DEFAULT CHARACTER SET latin1
    COLLATE latin1_general_cs AUTO_INCREMENT=0;

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


3

Выбор SQL не чувствителен к регистру.

Эта ссылка может показать вам, как сделать с учетом регистра: http://web.archive.org/web/20080811231016/http://sqlserver2000.databases.aspfaq.com:80/how-can-i-make-my- SQL-запросы регистра-sensitive.html


4
Зависит от вашей базы данных, как указано в другом месте здесь, они могут быть на MySQL.
Викирк


2

Также обратите внимание, что имена таблиц чувствительны к регистру в Linux, если вы не установили lower_case_table_nameдирективу config в 1 . Это потому, что таблицы представлены файлами, которые чувствительны к регистру в Linux.

Особенно остерегайтесь разработки под Windows, которая не чувствительна к регистру и развертывается на производстве, где она есть. Например:

"SELECT * from mytable" 

против таблицы myTable будет успешным в Windows, но не будет работать в Linux, опять же, если не установлена ​​вышеупомянутая директива.

Ссылка здесь: http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html


1
+1 - Сценарий написания нечувствительных к регистру запросов и последующего сбоя в Linux часто случался в нашем проекте
Vic

@Vic У меня такая же проблема с моим проектом. Подскажите, пожалуйста, как вы это исправили?
Камран Ахмед

@KamranAhmed, вам нужно использовать регистр имен таблиц в точности так, как они появляются в сценариях создания
Вик

@Vic, это было бы последним средством, так как мне пришлось бы изменять буквально тонны запросов. Мне было интересно, есть ли какой-нибудь простой способ сделать это. Спасибо хоть!
Кямран Ахмед

@KamranAhmed, попробуйте изменить, lower_case_table_nameкак указано в ответе, под которым мы комментируем
Вик

1

В настоящее время принятое решение является в основном правильным.

Если вы используете недвоичную строку (CHAR, VARCHAR, TEXT), сравнения не чувствительны к регистру в соответствии с параметрами сортировки по умолчанию.

Если вы используете двоичную строку (BINARY, VARBINARY, BLOB), сравнения выполняются с учетом регистра, поэтому вам нужно использовать, LOWERкак описано в других ответах.

Если вы не используете параметры сортировки по умолчанию и используете небинарную строку, чувствительность к регистру определяется выбранным параметром сортировки.

Источник: https://dev.mysql.com/doc/refman/8.0/en/case-sensitivity.html . Читайте внимательно. Некоторые ошибочно считают, что сравнения обязательно чувствительны к регистру или нечувствительны. Это не вариант.


0

Можешь попробовать. надеюсь это будет полезно.

SELECT * FROM `table` WHERE `Value` COLLATE latin1_general_cs = "IAreSavage"

0

Строковые поля с установленным двоичным флагом всегда будут чувствительны к регистру. Если вам нужен регистрозависимый поиск для недвоичного текстового поля, используйте это: SELECT 'test' REGEXP BINARY 'TEST' AS RESULT;

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.