大文字と小文字が混在する5文字を返す関数があります。この文字列に対してクエリを実行すると、大文字と小文字に関係なく値が返されます。
MySQLの文字列クエリで大文字と小文字を区別するにはどうすればよいですか?
http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.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 * FROM `table` WHERE BINARY `column` = 'value'
=演算子を使用する代わりに、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'を取ります
回答がCraig Whiteに投稿されました、パフォーマンスに大きなペナルティがあります
SELECT * FROM `table` WHERE BINARY `column` = 'value'
それはインデックスを使わないからです。そのため、ここで述べるようにテーブルの照合順序を変更する必要があります https://dev.mysql.com/doc/refman/5.7/en/case-sensitivity.html 。
OR
最も簡単な解決策は、値のバイナリを使用する必要があります。
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秒)
BINARYを使用する前にインデックスを利用するには、大きなテーブルがある場合はこのようにすることができます。
SELECT
*
FROM
(SELECT * FROM `table` WHERE `column` = 'value') as firstresult
WHERE
BINARY `column` = 'value'
サブクエリの結果、大文字と小文字が区別されない非常に小さいサブセットが生成され、その中から大文字と小文字を区別する唯一の一致が選択されます。
以下は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-sensitivity.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 |
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
DBレベルでは何も変更する必要はありません。動作するのはSQLクエリで変更するだけです。
例 -
"SELECT * FROM <TABLE> where userId = '" + iv_userId + "' AND password = BINARY '" + iv_password + "'";
バイナリキーワードでは大文字と小文字が区別されます。
優秀な!
私はあなたと共有します、パスワードを比較する関数からのコード:
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;
問合せ対象の列の照合順序を変更せずに大文字と小文字を区別する文字列比較を実行する最も正確な方法は、列の比較対象の値に対して文字セットと照合順序を明示的に指定することです。
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
とは何ですか?MySqlのutf8
文字セットは、4バイト文字(????のような文字列のエンコードに重要)をサポートしていないため、 最近のバージョンでは非推奨 となっているutf8mb3
のエイリアスです。 MySqlで TF8文字エンコード を使用したい場合は、utf8mb4
文字セットを使用してください。
mysqlはデフォルトでは大文字と小文字を区別しません。言語の照合順序をlatin1_general_cs
に変更してみてください