Pilih case MySQL tidak sensitif


242

Adakah yang bisa memberi tahu saya jika SELECTkueri MySQL adalah case-sensitive atau case-insensitive secara default? Dan jika tidak, permintaan apa yang harus saya kirim agar saya dapat melakukan sesuatu seperti:

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

Dimana dalam kenyataannya, nilai sebenarnya Valueadalah IAreSavage.


44
Pada akhirnya itu tergantung pada pengumpulan yang diajukan - apakah itu '_ci' (case-insensitive) atau '_cs' (case-sensitive)
Jovan Perovic

15
Ini adalah salah satu pertanyaan dengan kata yang buruk;). Separuh jawaban menunjukkan kepada Anda bagaimana melakukan perbandingan tidak peka huruf besar-kecil, setengah lainnya bertujuan untuk peka huruf besar-kecil. Dan hanya 1 yang memberi tahu Anda bahwa default sebenarnya tidak sensitif huruf. :) Perlu dicatat bahwa ketidakpekaan kasus berfungsi bahkan ketika Anda melakukan perbandingan seperti'value' in ('val1', 'val2', 'val3')
SaltyNuts

5
@SaltyNuts man, membaca pertanyaan ini 7 tahun kemudian dan menyadari betapa noob saya memalukan! Saya bisa saja membaca dokumentasi dan jawabannya adalah seperti kalimat pertama tentang pernyataan SELECT ...
NoodleOfDeath

Untuk menambahkan apa yang dikatakan @JovanPerovic, utf8_bin juga membuatnya case sensitif. Tidak yakin apakah itu ada saat itu
Chiwda

Jawaban:


494

Mereka tidak peka huruf besar kecil , kecuali Anda melakukan perbandingan biner .


3
Saya sebagian besar setuju dengan komentar Tim, saya tidak berpikir melakukan "lebih rendah ()" pada nilai-nilai Anda di mana-mana adalah cara terbaik untuk menanganinya, sepertinya solusi. Tapi saya akui itu kadang masuk akal dan lebih mudah. (Colin memang menyebutkan collate lebih baik) Kami memiliki data historis yang dipindahkan ke tabel mysql yang memecahkan logika legacy karena nilai kolom tertentu memiliki case yang tidak sensitif. Kami perlu tahu perbedaan antara "GE1234" dan "ge1234", mereka harus unik dan tetap seperti itu. Kami menetapkan kolom kami dalam membuat pernyataan tabel dengan cara ini sebagai gantinya: varchar (20) CHARACTER SET utf8 COLLATE utf8_bin
gregthegeek

19
Saya tidak tahu mengapa begitu banyak orang memilih ini. Ini dengan jelas menyatakan di sini dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html bahwa "... ini berarti bahwa untuk karakter alfabet, perbandingan akan peka huruf besar-kecil." Jadi jika saya mencari 'DickSavagewood' itu TIDAK akan mengambil 'dicksavagewood'. Melakukan hal yang sama dengan RENDAH () AKAN mengambilnya. Jadi jawaban saya untuk pertanyaan: dalam kasus khusus Anda SELECT memang case-sensitive.
Luftwaffle

10
@ user1961753: Baca lagi: "Untuk string biner (varbinary, blob) ... akan case-sensitive".
Marc B

1
@MarcB tautan ini sekarang rusak. Bisakah Anda memperbaikinya? :)
Phiter

5
Seperti yang dikatakan Jovan, itu tergantung pada susunannya, jadi jawaban ini sangat salah.
phil294

117

Anda dapat mengurangi nilai dan parameter yang diteruskan:

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

Cara lain (yang lebih baik) adalah menggunakan COLLATEoperator seperti yang disebutkan dalam dokumentasi


21
Bagaimana SELECTpernyataan ini terlihat menggunakan COLLATEitu?
Ya Barry

11
Dikatakan, pada halaman dokumentasi yang disebutkan di atas, bahwa "perbandingan string non-biner adalah case-sensitive secara default".
Per Quested Aronsson

9
Agak menakutkan berapa banyak orang yang mengangkat jawaban ini. Seperti yang dijelaskan oleh @Marc di atas, perbandingan tidak peka huruf besar-kecil. Anda perlu memahami kumpulan dan indeks dan mengonfigurasinya dengan benar - menggunakan transformasi string seperti LOWER()atau COLLATEklausa sewenang-wenang dapat sepenuhnya mem-bypass indeks, dan seiring waktu, seiring pertumbuhan tabel Anda, ini dapat memiliki implikasi kinerja yang drastis. Kemungkinan ini adalah nama pengguna yang Anda cari? Gunakan susunan case-insensitive dan tambahkan indeks unik ke kolom. Gunakan EXPLAINuntuk mengonfirmasi bahwa indeks sedang digunakan.
mindplay.dk

1
Saya akan mengatakan hal yang sama dengan mindplay.dk ... atas () dan lebih rendah () memintas indeks dan secara langsung mempengaruhi kinerja pada tabel database besar.
GTodorov

Saya menyetujui pendapat mindplay.dk dan GTodorov. Hati-hati menggunakan beberapa metode pada kolom target di mana klausa. Indeks kolom bisa tidak berguna. Gunakan JELASKAN!
pengkhianat

51

GUNAKAN BINARY

Ini adalah pilihan sederhana

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

= 1

Ini adalah pilih dengan biner

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

atau

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

= 0


3
Kapan masuk akal untuk menggunakan BINARY hanya pada satu sisi = (SELECT * DARI myTable WHERE BINARY 'something' = 'Something')?
Jimmy

@ Jimmy Apa maksudmu sebenarnya? Kode berfungsi. Ketika satu sisi dalam perbandingan dilemparkan ke biner, perbandingan dilakukan biner.
Jori

@ Jori Oh, saya kira saya salah membaca - saya pikir salah satu dari dua contoh memiliki BINARY di kedua sisi sama.
Jimmy

Saya baru saja memilih ini karena ini benar-benar jawaban yang tepat. Menurut dokumentasi di situs web MySQL, mereka mengatakan lebih baik menggunakan perintah BINARY daripada mencoba mengetik kata-kata / permintaan Anda ke dalam bahasa tertentu karena perintah BINARY mengatakan untuk membiarkan semua yang ada seperti itu dan menggunakannya persis seperti itu disajikan. Jadi ketika saya datang untuk mencari jawaban - dua jawaban di sini membawa saya ke situs web MySQL dan untuk melihat dokumen mereka. Menggunakan BINARY lebih baik. Menerjemahkan dapat menyebabkan masalah lain.
Mark Manning

43

Perbandingan adalah case-sensitive ketika kolom menggunakan collation yang diakhiri dengan _ci(seperti collation default latin1_general_ci ) dan mereka case-sensitive ketika kolom menggunakan collation yang diakhiri dengan _csatau _bin(seperti utf8_unicode_csdan utf8_bincollations).

Periksa susunan

Anda dapat memeriksa server , basis data , dan koneksi Anda menggunakan:

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

dan Anda dapat memeriksa susunan tabel Anda menggunakan:

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 |

Ubah susunan

Anda dapat mengubah basis data, tabel, atau kolom Anda menjadi sesuatu yang sensitif huruf sebagai berikut:

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

Perbandingan Anda sekarang harus peka terhadap huruf besar-kecil.


25

Perbandingan string dalam frase WHERE tidak peka huruf besar-kecil. Anda dapat mencoba membandingkan menggunakan

WHERE `colname` = 'keyword'

atau

WHERE `colname` = 'KeyWord'

dan Anda akan mendapatkan hasil yang sama . Itu adalah perilaku default MySQL.

Jika Anda ingin perbandingan menjadi peka huruf besar-kecil , Anda dapat menambahkan COLLATEseperti ini:

WHERE `colname` COLLATE latin1_general_cs = 'KeyWord'

SQL itu akan memberikan hasil yang berbeda dengan yang ini: WHERE colnameCOLLATE latin1_general_cs = 'kata kunci'

latin1_general_cs adalah pemeriksaan umum atau standar di sebagian besar basis data.


16

Susunan yang Anda pilih menetapkan apakah Anda peka huruf besar kecil atau kecil.


9

Defaultnya adalah case-sensitive, tetapi hal terpenting berikutnya yang harus Anda perhatikan adalah bagaimana tabel itu dibuat di tempat pertama, karena Anda dapat menentukan sensitivitas case ketika Anda membuat tabel.

Script di bawah ini membuat tabel. Perhatikan di bagian bawah tertulis "COLLATE latin1_general_cs". Bahwa cs pada akhirnya berarti case sensitif. Jika Anda ingin meja Anda menjadi case-sensitive Anda akan meninggalkan bagian itu atau menggunakan "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;

Jika proyek Anda sedemikian rupa sehingga Anda dapat membuat tabel Anda sendiri, maka masuk akal untuk menentukan preferensi sensitivitas kasus Anda saat Anda membuat tabel.




2

Perhatikan juga bahwa nama tabel peka huruf besar-kecil di Linux kecuali jika Anda mengatur lower_case_table_namedirektif konfigurasi ke 1 . Ini karena tabel diwakili oleh file yang peka huruf besar kecil di Linux.

Terutama waspadalah terhadap pengembangan pada Windows yang tidak peka huruf besar-kecil dan menggunakan untuk produksi di tempat itu. Sebagai contoh:

"SELECT * from mytable" 

terhadap tabel myTable akan berhasil di Windows tetapi gagal di Linux, lagi, kecuali direktif di atas diatur.

Referensi di sini: http://dev.mysql.com/doc/refman/5.0/id/identifier-case-sensitivity.html


1
+1 - Skenario penulisan kueri yang tidak peka terhadap kasus dan kemudian gagal di Linux banyak terjadi di proyek kami
Vic

@Vic Saya mengalami masalah yang sama dengan proyek saya. Bisakah Anda memberi tahu saya bagaimana Anda memperbaikinya?
Kamran Ahmed

@ KamranAhmed, Anda harus menggunakan casing nama tabel persis seperti yang muncul di skrip pembuatan
Vic

@Vic itu akan menjadi pilihan terakhir, karena saya harus memodifikasi banyak pertanyaan. Saya bertanya-tanya, apakah akan ada cara mudah untuk melakukannya. Terimakasih Meskipun!
Kamran Ahmed

@KamranAhmed, cobalah untuk mengubah lower_case_table_nameseperti yang ditentukan dalam jawaban yang kami komentari
Vic

1

Solusi yang saat ini diterima sebagian besar benar.

Jika Anda menggunakan string non-biner (CHAR, VARCHAR, TEXT), perbandingan tidak peka huruf besar-kecil , sesuai susunan standar.

Jika Anda menggunakan string biner (BINARY, VARBINARY, BLOB), perbandingan bersifat case-sensitive, jadi Anda harus menggunakan LOWERseperti yang dijelaskan dalam jawaban lain.

Jika Anda tidak menggunakan collation default dan Anda menggunakan string non-biner, sensitivitas case ditentukan oleh collation yang dipilih.

Sumber: https://dev.mysql.com/doc/refman/8.0/id/case-sensitivity.html . Baca dengan cermat. Beberapa yang lain salah mengartikannya bahwa perbandingan harus peka terhadap huruf besar atau kecil. Ini bukan kasusnya.


0

Kamu bisa mencobanya. semoga bermanfaat.

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

0

Bidang string dengan set bendera biner akan selalu peka huruf besar-kecil. Jika Anda memerlukan pencarian case-sensitive untuk bidang teks non-biner, gunakan ini: SELECT 'test' REGEXP BINARY 'TEST' SEBAGAI HASIL;

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.