大文字と小文字が混在する5文字を返す関数があります。この文字列に対してクエリを実行すると、大文字小文字に関係なく値が返されます。
MySQL文字列クエリで大文字と小文字を区別するにはどうすればよいですか?
大文字と小文字が混在する5文字を返す関数があります。この文字列に対してクエリを実行すると、大文字小文字に関係なく値が返されます。
MySQL文字列クエリで大文字と小文字を区別するにはどうすればよいですか?
回答:
http://dev.mysql.com/doc/refman/5.0/en/case-sensitiveivity.html
デフォルトの文字セットと照合はlatin1とlatin1_swedish_ciであるため、非バイナリ文字列の比較では、デフォルトで大文字と小文字が区別されません。つまり、col_name LIKE 'a%'で検索すると、Aまたはaで始まるすべての列の値が取得されます。この検索で大文字と小文字を区別するには、オペランドの1つに大文字と小文字の区別またはバイナリ照合があることを確認してください。たとえば、どちらもlatin1文字セットを持つ列と文字列を比較する場合は、COLLATE演算子を使用して、いずれかのオペランドにlatin1_general_csまたはlatin1_bin照合順序を設定できます。
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
常に大文字と小文字を区別する方法で列を処理する場合は、大文字と小文字を区別する照合またはバイナリ照合で列を宣言します。
SELECT 'email' COLLATE utf8_bin = 'Email'
良い知らせは、大文字と小文字を区別するクエリを作成する必要がある場合、非常に簡単に実行できることです。
SELECT * FROM `table` WHERE BINARY `column` = 'value'
convert(char(0x65,0xcc,0x88) using utf8)
(つまりe
、¨
追加あり)とconvert(char(0xc3,0xab) using utf8)
(つまり、ë
)として同等に扱うことができますが、追加BINARY
すると、等しくなくなります。
クレイグホワイトが投稿した回答には、大きなパフォーマンスペナルティがあります。
SELECT * FROM `table` WHERE BINARY `column` = 'value'
インデックスを使用しないためです。したがって、https: //dev.mysql.com/doc/refman/5.7/en/case-sensitiveivity.htmlのように、テーブルの照合順序を変更する必要があります。
または
最も簡単な修正は、BINARY値を使用することです。
SELECT * FROM `table` WHERE `column` = BINARY 'value'
例えば。
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
セット内の1行(0.00秒)
=演算子を使用する代わりに、LIKEまたはLIKE BINARYを使用することができます
// 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'
状態は「A」ではなく「A」になります
BINARYを使用する前にインデックスを使用するには、大きなテーブルがある場合に、次のようにします。
SELECT
*
FROM
(SELECT * FROM `table` WHERE `column` = 'value') as firstresult
WHERE
BINARY `column` = 'value'
サブクエリを実行すると、大文字と小文字が区別されない非常に小さなサブセットが生成され、そのサブセットで大文字と小文字を区別する一致のみを選択します。
クエリ対象の列の照合順序を変更せずに大文字と小文字を区別する文字列比較を実行する最も正しい方法は、列が比較される値の文字セットと照合順序を明示的に指定することです。
select * from `table` where `column` = convert('value' using utf8mb4) collate utf8mb4_bin;
binary
ですか?binary
演算子はエンコードされた文字列の実際のバイトを比較するため、演算子の使用はお勧めできません。異なる文字セットを使用してエンコードされた2つの文字列の実際のバイトを比較すると、同じと見なされるべき2つの文字列は等しくない場合があります。たとえば、latin1
文字セットを使用する列があり、サーバー/セッションの文字セットがutf8mb4
である場合、その列を 'café'などのアクセントを含む文字列と比較すると、同じ文字列を含む行とは一致しません。これは、latin1
éはバイトとしてエンコードされます0xE9
が、utf8
2バイトであるためです0xC3A9
。
convert
同様に使用するのcollate
ですか?照合順序は文字セットと一致する必要があります。したがって、サーバーまたはセッションがlatin1
文字セットを使用するように設定されている場合は使用する必要collate latin1_bin
がありますが、文字セットがutf8mb4
使用されている場合は使用する必要がありますcollate utf8mb4_bin
。したがって、最も堅牢なソリューションは、常に値を最も柔軟な文字セットに変換し、その文字セットにバイナリ照合を使用することです。
convert
とcollate
を列ではなく値に適用するのはなぜですか?比較を行う前に変換関数を列に適用すると、列にインデックスが存在する場合にクエリエンジンがインデックスを使用できなくなり、クエリが大幅に遅くなる可能性があります。したがって、可能な場合は常に値を変換する方が常に適切です。2つの文字列値の間で比較が実行され、そのうちの1つに明示的に指定された照合がある場合、クエリエンジンは、適用される値に関係なく、明示的な照合を使用します。
MySqlは、_ci
照合順序(通常はデフォルト)を使用する列の大文字と小文字を区別するだけでなく、アクセント記号も区別しないことに注意することが重要です。つまり'é' = 'e'
。バイナリ照合(またはbinary
演算子)を使用すると、文字列の比較でアクセントと大文字と小文字が区別されます。
utf8mb4
?utf8
MySQLでの文字セットはのための別名ですutf8mb3
されている最近のバージョンで非推奨、それは(🐈のような文字列を符号化するために重要である)、4つのバイト文字をサポートしていないため。MySqlでUTF8文字エンコーディングを使用する場合は、utf8mb4
文字セットを使用する必要があります。
以下は、MySQLバージョンが5.5以上の場合です。
/etc/mysql/my.cnfに追加します
[mysqld]
...
character-set-server=utf8
collation-server=utf8_bin
...
私が試した他のすべての照合は大文字と小文字を区別しないようで、「utf8_bin」のみが機能しました。
この後、mysqlを再起動することを忘れないでください。
sudo service mysql restart
http://dev.mysql.com/doc/refman/5.0/en/case-sensitiveivity.htmlによると、「latin1_bin」もあります。
「utf8_general_cs」は、mysqlの起動で受け入れられませんでした。(「_cs」を「大文字と小文字を区別する」と読みました-???)。
BINARYを使用して、このように大文字と小文字を区別することができます
select * from tb_app where BINARY android_package='com.Mtime';
残念ながら、このsqlはインデックスを使用できません。そのインデックスに依存するクエリでパフォーマンスヒットが発生します
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 |
+----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
幸いにも、私はこの問題を解決するためのいくつかのトリックを持っています
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 |
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
優れた!
パスワードを比較する関数のコードを共有します。
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;
最初に追加する必要があります