Karışık karakter ile beş karakter döndüren bir işlevi var. Bu dizede bir sorgu yaparsanız, durum ne olursa olsun değeri döndürür.
MySQL dizesi sorgularını büyük / küçük harfe duyarlı hale nasıl getirebilirim?
Karışık karakter ile beş karakter döndüren bir işlevi var. Bu dizede bir sorgu yaparsanız, durum ne olursa olsun değeri döndürür.
MySQL dizesi sorgularını büyük / küçük harfe duyarlı hale nasıl getirebilirim?
Yanıtlar:
http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html
Varsayılan karakter kümesi ve harmanlama latin1 ve latin1_swedish_ci şeklindedir, bu nedenle ikili olmayan dize karşılaştırmaları varsayılan olarak büyük / küçük harfe duyarlı değildir. Diğer bir deyişle, 'a%' sütun_adı ile arama yaparsanız, A veya a ile başlayan tüm sütun değerlerini alırsınız. Bu arama büyük / küçük harfe duyarlı hale getirmek için, işlenenlerden birinin büyük / küçük harfe duyarlı veya ikili harmanlama olduğundan emin olun. Örneğin, her ikisi de latin1 karakter kümesine sahip bir sütun ve bir dize karşılaştırıyorsanız, işlenenlerden birinin latin1_general_cs veya latin1_bin harmanlamasına sahip olmasını sağlamak için COLLATE işlecini kullanabilirsiniz:
col_name COLLATE latin1_general_cs LIKE 'a%'
col_name LIKE 'a%' COLLATE latin1_general_cs
col_name COLLATE latin1_bin LIKE 'a%'
col_name LIKE 'a%' COLLATE latin1_bin
Bir sütunun her zaman büyük / küçük harfe duyarlı şekilde işlenmesini istiyorsanız, büyük / küçük harfe duyarlı veya ikili bir harmanlama ile bildirin.
SELECT 'email' COLLATE utf8_bin = 'Email'
İyi haber şu ki, büyük / küçük harfe duyarlı bir sorgu yapmanız gerekiyorsa, bunu yapmak çok kolaydır:
SELECT * FROM `table` WHERE BINARY `column` = 'value'
convert(char(0x65,0xcc,0x88) using utf8)
(yani e
birlikte ¨
eklendi) ve convert(char(0xc3,0xab) using utf8)
(yani ë
), ancak ekleyerek BINARY
onları eşitsiz hale getirecektir.
Tarafından gönderildi Craig White, büyük performans cezası var
SELECT * FROM `table` WHERE BINARY `column` = 'value'
çünkü dizin kullanmıyor. Bu nedenle, tablo harmanlamasını burada belirtildiği gibi değiştirmeniz gerekir https://dev.mysql.com/doc/refman/5.7/en/case-sensitivity.html .
VEYA
En kolay düzeltme, bir BINARY değeri kullanmalısınız.
SELECT * FROM `table` WHERE `column` = BINARY 'value'
Örneğin.
mysql> EXPLAIN SELECT * FROM temp1 WHERE BINARY col1 = "ABC" AND col2 = "DEF" ;
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | temp1 | ALL | NULL | NULL | NULL | NULL | 190543 | Using where |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
VS
mysql> EXPLAIN SELECT * FROM temp1 WHERE col1 = BINARY "ABC" AND col2 = "DEF" ;
+----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
| 1 | SIMPLE | temp1 | range | col1_2e9e898e | col1_2e9e898e | 93 | NULL | 2 | Using index condition; Using where |
+----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
enter code here
Sette 1 satır (0.00 sn)
= İşlecini kullanmak yerine, GİBİ veya GİBİ İKİLİ gibi kullanmak isteyebilirsiniz
// this returns 1 (true)
select 'A' like 'a'
// this returns 0 (false)
select 'A' like binary 'a'
select * from user where username like binary 'a'
Durumunda 'A' değil 'a' alacaktır
İKİLİ'yi kullanmadan önce bir dizinden yararlanmak için büyük tablolarınız varsa böyle bir şey yapabilirsiniz.
SELECT
*
FROM
(SELECT * FROM `table` WHERE `column` = 'value') as firstresult
WHERE
BINARY `column` = 'value'
Alt sorgu, küçük / büyük harfe duyarlı olmayan bir alt kümeyle sonuçlanır.
Sorgulanan sütunun harmanlamasını değiştirmeden büyük / küçük harfe duyarlı bir dize karşılaştırması yapmanın en doğru yolu, sütunun karşılaştırıldığı değer için açıkça bir karakter kümesi ve harmanlama belirtmektir.
select * from `table` where `column` = convert('value' using utf8mb4) collate utf8mb4_bin;
binary
?Kullanılması binary
o kodlanmış dizeleri gerçek byte karşılaştırır çünkü operatörü önerilmez. Farklı karakter kümeleri kullanılarak kodlanan iki dizenin gerçek baytlarını karşılaştırırsanız, aynı kabul edilmesi gereken iki dizge eşit olmayabilir. Örneğin, latin1
karakter kümesini kullanan bir sütununuz varsa ve sunucu / oturum karakter kümeniz ise utf8mb4
, sütunu 'café' gibi bir aksan içeren bir dize ile karşılaştırdığınızda, aynı dizeyi içeren satırlarla eşleşmez! İçinde olmasıdır latin1
é byte olarak kodlanan 0xE9
ama utf8
iki bayt: 0xC3A9
.
convert
sıra sıra collate
?Harmanlamalar karakter kümesiyle eşleşmelidir. Bu nedenle sunucunuz veya oturumunuz latin1
karakter kümesini kullanacak şekilde ayarlanmışsa, kullanmanız gerekir collate latin1_bin
ancak karakter kümeniz ise utf8mb4
kullanmanız gerekir collate utf8mb4_bin
. Bu nedenle en sağlam çözüm, değeri her zaman en esnek karakter kümesine dönüştürmek ve bu karakter kümesi için ikili harmanlamayı kullanmaktır.
convert
ve collate
değerini sütuna değil, değere uygulayın ?Bir karşılaştırma yapmadan önce bir sütuna herhangi bir dönüştürme işlevi uyguladığınızda, sorgu motorunun sütun için bir dizin varsa, sorgunuzu önemli ölçüde yavaşlatabilecek bir dizin kullanmasını engeller. Bu nedenle değeri mümkün olan yerlerde dönüştürmek her zaman daha iyidir. İki dize değeri arasında bir karşılaştırma yapıldığında ve bunlardan birinde açıkça belirtilen bir harmanlama varsa, sorgu motoru hangi değere uygulandığına bakılmaksızın açık harmanlamayı kullanır.
MySql'in yalnızca bir _ci
harmanlama (genellikle varsayılan olan) kullanan sütunlar için büyük / küçük harfe duyarlı olmadığını , aynı zamanda aksan duyarlı olmadığını da belirtmek önemlidir . Bu demektir 'é' = 'e'
. İkili bir harmanlama (veya binary
operatör) kullanmak, dize karşılaştırmalarını aksan duyarlı olduğu kadar büyük / küçük harf duyarlı hale getirir.
utf8mb4
?utf8
MySql karakter kümesi için bir takma ad utf8mb3
edildiği son sürümlerinde kaldırılmış o (🐈 gibi dizeleri kodlamak için önemlidir) 4 baytlık karakterleri desteklemediği için. Kullanmak isterseniz UTF8 karakter kodlamasını MySQL ile ardından kullanmakta olmalıdır utf8mb4
charset.
Aşağıda 5.5'e eşit veya daha yüksek MySQL sürümleri bulunmaktadır.
/Etc/mysql/my.cnf dosyasına ekle
[mysqld]
...
character-set-server=utf8
collation-server=utf8_bin
...
Denediğim diğer tüm harmanlamalar büyük / küçük harfe duyarlı görünmüyordu, sadece "utf8_bin" çalıştı.
Bundan sonra mysql'yi yeniden başlatmayı unutmayın:
sudo service mysql restart
Http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html'ye göre bir de "latin1_bin" var.
"Utf8_general_cs" mysql başlangıcı tarafından kabul edilmedi. ("_Cs" i "büyük / küçük harfe duyarlı" olarak okudum - ???).
BINARY işlevini, bu gibi hassas durumlar için kullanabilirsiniz
select * from tb_app where BINARY android_package='com.Mtime';
ne yazık ki bu sql endeksi kullanamaz, bu endekse bağlı sorgularda bir performans isabeti çekeceksiniz
mysql> explain select * from tb_app where BINARY android_package='com.Mtime';
+----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
| 1 | SIMPLE | tb_app | NULL | ALL | NULL | NULL | NULL | NULL | 1590351 | 100.00 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
Neyse ki, bu sorunu çözmek için birkaç hilem var
mysql> explain select * from tb_app where android_package='com.Mtime' and BINARY android_package='com.Mtime';
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
| 1 | SIMPLE | tb_app | NULL | ref | idx_android_pkg | idx_android_pkg | 771 | const | 1 | 100.00 | Using index condition |
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
Mükemmel!
Sizinle, şifreleri karşılaştıran bir fonksiyondan kod paylaşıyorum:
SET pSignal =
(SELECT DECODE(r.usignal,'YOURSTRINGKEY') FROM rsw_uds r WHERE r.uname =
in_usdname AND r.uvige = 1);
SET pSuccess =(SELECT in_usdsignal LIKE BINARY pSignal);
IF pSuccess = 1 THEN
/*Your code if match*/
ELSE
/*Your code if don't match*/
END IF;
declare pSuccess BINARY;
Başlangıçta eklemeniz gerekiyor
DB düzeyinde bir şey değiştirmeye gerek yok, sadece çalışacak SQL Sorgu değişiklikleri yapmanız gerekir.
Misal -
"SELECT * FROM <TABLE> where userId = '" + iv_userId + "' AND password = BINARY '" + iv_password + "'";
İkili anahtar kelime büyük / küçük harfe duyarlı hale getirir.