MySQL nie rozróżnia wielkości liter

242

Czy ktoś może mi powiedzieć, czy SELECTzapytanie MySQL domyślnie rozróżnia małe i wielkie litery? A jeśli nie, jakie zapytanie musiałbym wysłać, aby móc zrobić coś takiego:

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

W rzeczywistości rzeczywistą wartością Valuejest IAreSavage.

NoodleOfDeath
źródło
44
Ostatecznie zależy to od złożonego sortowania - jeśli jest to „_ci” (bez uwzględniania wielkości liter) lub „_cs” (z uwzględnieniem wielkości liter)
Jovan Perovic
15
To jedno źle sformułowane pytanie;). Połowa odpowiedzi pokazuje, jak przeprowadzić porównanie bez rozróżniania wielkości liter, a połowa zmierza do rozróżniania wielkości liter. I tylko 1 mówi ci, że domyślnie nie uwzględnia wielkości liter. :) Warto zauważyć, że rozróżnianie wielkości liter działa nawet wtedy, gdy wykonujesz porównanie typu'value' in ('val1', 'val2', 'val3')
SaltyNuts,
5
@ Mężczyzna z SaltNuts, czytając to pytanie 7 lat później i zdając sobie sprawę, jak bardzo byłam noobem, jest zawstydzająca! Mógłbym po prostu przeczytać dokumentację, a odpowiedź brzmi jak pierwsze zdanie na temat instrukcji SELECT ...
NoodleOfDeath
Aby dodać do tego, co powiedział @JovanPerovic, utf8_bin również rozróżnia wielkość liter. Nie jestem pewien, czy to wtedy istniało
Chiwda,

Odpowiedzi:

494

wrażliwe na wielkość liter , chyba że zrobić porównanie binarne .

Marc B.
źródło
3
W większości zgadzam się z komentarzem Tima, nie sądzę, aby stosowanie „lower ()” dla twoich wartości było najlepszym sposobem na poradzenie sobie z tym, wydaje się to obejściem. Ale przyznaję, że czasami ma to sens i jest łatwiejsze. (Colin wspomniał, że sortowanie jest lepsze) Mieliśmy dane historyczne przeniesione do tabeli mysql, co złamało starą logikę z powodu pewnych wartości kolumn mających niewrażliwy przypadek. Musieliśmy znać różnicę między „GE1234” a „ge1234”, musieli być wyjątkowi i pozostać zalogowani w ten sposób. Zamiast tego ustawiamy naszą kolumnę w instrukcji tworzenia tabeli: varchar (20)
ZNAK ZESTAWU
19
Nie wiem, dlaczego tak wielu ludzi to zagłosowało. Wyraźnie stwierdza tutaj dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html, że „… oznacza to, że w przypadku znaków alfabetycznych rozróżniana jest wielkość liter”. Więc jeśli szukam „DickSavagewood”, NIE wyłapałbym „dicksavagewood”. Robiąc to samo z LOWER () BĘDZIE to podnosić. Tak więc moja odpowiedź na pytanie: w twoim przypadku SELECT rzeczywiście rozróżnia małe i wielkie litery.
Luftwaffle,
10
@ user1961753: Przeczytaj ponownie: „W przypadku ciągów binarnych (varbinary, blob) ... rozróżniana jest wielkość liter”.
Marc B,
1
@MarcB ten link jest teraz uszkodzony. Czy możesz to naprawić? :)
Phiter
5
Jak powiedział Jovan, zależy to od ułożenia, więc ta odpowiedź jest całkiem błędna.
phil294
117

Możesz pomniejszyć wartość i przekazany parametr:

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

Innym (lepszym) sposobem byłoby użycie COLLATEoperatora, jak wspomniano w dokumentacji

Colin Hebert
źródło
21
Jak wówczas wyglądałoby to SELECToświadczenie COLLATE?
Tak Barry
11
Na powyższej stronie dokumentacji napisano, że „niebinarne porównania ciągów domyślnie nie uwzględniają wielkości liter”.
Per Quested Aronsson
9
Przerażające, ile osób głosowało za odpowiedzią. Jak wyjaśnia powyżej @Marc, w porównaniach nie jest rozróżniana wielkość liter. Musisz zrozumieć zestawienia i indeksy oraz odpowiednio je skonfigurować - użycie transformacji ciągów takich jak LOWER()lub dowolna COLLATEklauzula może całkowicie ominąć indeks, a wraz z upływem czasu, wraz ze wzrostem tabeli, może to mieć drastyczny wpływ na wydajność. Czy to są nazwy użytkowników, których szukasz? Użyj sortowania bez rozróżniania wielkości liter i dodaj unikalny indeks do kolumny. Użyj, EXPLAINaby potwierdzić, że indeks jest używany.
mindplay.dk
1
Już miałem powiedzieć to samo, co mindplay.dk ... górne () i dolne () pomijają indeks i bezpośrednio wpływają na wydajność dużych tabel baz danych.
GTodorov
Zgadzam się zarówno z opiniami mindplay.dk, jak i GTodorova. Zachowaj ostrożność, stosując jakąś metodę na kolumnie docelowej w klauzuli where. Indeks kolumny może być bezużyteczny. Użyj WYJAŚNIJ!
traeper
51

WYKORZYSTAJ BINARY

To jest prosty wybór

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

= 1

To jest wybór z binarnym

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

lub

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

= 0

Ktoś
źródło
3
Kiedy ma sens użycie BINARY po tylko jednej stronie znaku = (WYBIERZ * z myTable GDZIE BINARY „coś” = „Coś”)?
Jimmy
@ Jimmy Co dokładnie masz na myśli? Kod działa. Kiedy jedna strona porównania jest rzutowana na binarną, porównanie jest wykonywane binarnie.
Jori,
@Jori Och, chyba źle odczytałem - myślałem, że jeden z dwóch przykładów ma BINARY po obu stronach równości.
Jimmy
Właśnie głosowałem, ponieważ to naprawdę jest właściwa odpowiedź. Zgodnie z dokumentacją na stronie MySQL mówią, że lepiej jest użyć polecenia BINARY, niż próbować typecastować słowa / żądania w określonym języku, ponieważ polecenie BINARY mówi, aby pozostawić wszystko tak, jak jest i używać dokładnie tak, jak jest jest prezentowane. Więc kiedy przyszedłem szukać odpowiedzi - dwie odpowiedzi zaprowadziły mnie na stronę MySQL i przejrzałem ich dokumentację. Korzystanie z BINARY jest lepsze. Tłumaczenie może powodować inne problemy.
Mark Manning
43

Porównania nie uwzględniają wielkości liter, gdy kolumna używa sortowania, które kończy się na _ci(na przykład sortowanie domyślne latin1_general_ci ), i rozróżniają małe i wielkie litery, gdy kolumna używa sortowania, które kończy się na _cslub _bin(np. utf8_unicode_csI utf8_binsortowania).

Sprawdź układanie

Możesz sprawdzić serwer , bazę danych i zestawienia połączeń, używając:

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

i możesz sprawdzić sortowanie tabel za pomocą:

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 |

Zmień układanie

Możesz zmienić sortowanie bazy danych, tabeli lub kolumny na wielkość liter, w następujący sposób:

-- 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;

W twoich porównaniach rozróżniana jest teraz wielkość liter.

ostrokach
źródło
25

Porównanie ciągów w wyrażeniu GDZIE nie rozróżnia wielkości liter. Możesz spróbować porównać za pomocą

WHERE `colname` = 'keyword'

lub

WHERE `colname` = 'KeyWord'

i otrzymasz ten sam wynik . To jest domyślne zachowanie MySQL.

Jeśli chcesz, aby porównanie uwzględniało wielkość liter , możesz dodać COLLATEtak:

WHERE `colname` COLLATE latin1_general_cs = 'KeyWord'

Ten SQL dałby inny wynik z tym: WHERE colnameCOLLATE latin1_general_cs = 'keyword'

latin1_general_cs jest powszechnym lub domyślnym zestawieniem w większości baz danych.

Ifan Iqbal
źródło
16

Wybrane sortowanie określa, czy rozróżnia się wielkie i małe litery.

Chuck taylor
źródło
9

Domyślnie rozróżniana jest wielkość liter, ale następną najważniejszą rzeczą, na którą powinieneś zwrócić uwagę, jest sposób, w jaki tabela została utworzona, ponieważ możesz określić rozróżnianie wielkości liter podczas tworzenia tabeli.

Poniższy skrypt tworzy tabelę. Zauważ na dole, że jest napisane „COLLATE latin1_general_cs”. To cs na końcu oznacza, że ​​wielkość liter ma znaczenie. Jeśli chcesz, aby w tabeli nie rozróżniano wielkości liter, możesz pominąć tę część lub użyć polecenia „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;

Jeśli Twój projekt umożliwia utworzenie własnej tabeli, sensowne jest określenie preferencji rozróżniania wielkości liter podczas tworzenia tabeli.

Ken Johnson
źródło
3

Spróbuj z:

order by lower(column_name) asc;
VS-Java
źródło
2

Zauważ również, że w nazwach tabel rozróżniana jest wielkość liter w systemie Linux, chyba że ustawisz lower_case_table_namedyrektywę config na 1 . Wynika to z faktu, że tabele są reprezentowane przez pliki, w których rozróżniana jest wielkość liter w systemie Linux.

Szczególnie uważaj na rozwój systemu Windows, który nie rozróżnia wielkich i małych liter, i wdrażanie go tam, gdzie jest. Na przykład:

"SELECT * from mytable" 

przeciwko tabeli myTable odniesie sukces w systemie Windows, ale w Linuksie ponownie, chyba że zostanie ustawiona wyżej wspomniana dyrektywa.

Odnośnik tutaj: http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html

Wes Grant
źródło
1
+1 - Scenariusz pisania zapytań bez rozróżniania wielkości liter, a następnie niepowodzenia na Linuxach zdarzał się często w naszym projekcie
Vic,
@ Vic Mam ten sam problem z moim projektem. Czy możesz mi powiedzieć, jak to naprawiłeś?
Kamran Ahmed
@KamranAhmed, musisz używać obudowy nazw tabel dokładnie tak, jak pojawiają się one w skryptach tworzenia
Vic
@Vic to byłby ostateczność, ponieważ musiałbym modyfikować dosłownie mnóstwo zapytań. Zastanawiałem się, czy byłby to łatwy sposób. W każdym razie dzięki!
Kamran Ahmed
@KamranAhmed, spróbuj zmienić lower_case_table_namezgodnie z odpowiedzią, pod którą komentujemy
Vic
1

Aktualnie akceptowane rozwiązanie jest w większości prawidłowe.

Jeśli używasz łańcucha niebinarnego (CHAR, VARCHAR, TEXT), w porównaniach nie jest rozróżniana wielkość liter , według domyślnego sortowania.

Jeśli używasz ciągu binarnego (BINARY, VARBINARY, BLOB), w porównaniach rozróżniana jest wielkość liter, więc musisz użyć LOWERopisanego w innych odpowiedziach.

Jeśli nie używasz domyślnego sortowania, a używasz łańcucha niebinarnego, o tym, czy wybrano sortowanie, decyduje wielkość liter.

Źródło: https://dev.mysql.com/doc/refman/8.0/en/case-sensitivity.html . Przeczytaj uważnie. Niektórzy inni mylnie stwierdzili, że w porównaniach z konieczności rozróżniana jest wielkość liter lub nie jest uwzględniana wielkość liter. Nie o to chodzi.

A248
źródło
0

Możesz tego spróbować. mam nadzieję, że się przyda.

SELECT * FROM `table` WHERE `Value` COLLATE latin1_general_cs = "IAreSavage"
Zahid
źródło
0

W polach ciągów z ustawioną flagą binarną zawsze będzie rozróżniana wielkość liter. Jeśli potrzebujesz rozróżnić małe i wielkie litery w polu tekstowym niebinarnym, użyj tego: WYBIERZ „test” REGEXP BINARNY „TEST” JAKO WYNIK;

użytkownik2288580
źródło