我如何才能使SQL区分大小写字符串比较MySQL?

我有一个函数,返回5个混合大小写字符。如果我对这个字符串进行查询,不管大小写,它都会返回值。

如何使MySQL字符串查询区分大小写?

323855 次浏览

好消息是,如果你需要进行区分大小写的查询,这很容易做到:

SELECT *  FROM `table` WHERE BINARY `column` = 'value'

http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html

默认的字符集和排序规则是latin1和latin1_swedish_ci,因此非二进制字符串比较在默认情况下不区分大小写。这意味着如果使用col_name LIKE 'a%'进行搜索,将得到所有以a或a开头的列值。要使此搜索区分大小写,请确保其中一个操作数具有区分大小写或二进制排序规则。例如,如果比较的列和字符串的字符集都为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

如果希望始终以区分大小写的方式对待列,请使用区分大小写或二进制排序规则来声明它。

mysql默认不区分大小写,请尝试将语言排序规则更改为latin1_general_cs

不使用=运算符,您可能希望使用LIKE或LIKE二进制

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

下面是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”读成“区分大小写”- ??)

太好了!

我和你们分享一个比较密码的函数的代码:

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;

要在使用BINARY之前使用索引,如果有大型表,可以这样做。

SELECT
*
FROM
(SELECT * FROM `table` WHERE `column` = 'value') as firstresult
WHERE
BINARY `column` = 'value'

子查询将生成一个非常小的不区分大小写的子集,然后选择其中唯一区分大小写的匹配项。

您可以像这样使用二进制区分大小写

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

克雷格·怀特(Craig White)发布的答案有很大的性能损失

SELECT *  FROM `table` WHERE BINARY `column` = 'value'

因为它不使用索引。所以,要么你需要改变表排序规则,就像这里提到的https://dev.mysql.com/doc/refman/5.7/en/case-sensitivity.html

最简单的解决方法,你应该使用二进制值。

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

set中的1行(0.00秒)

不需要改变任何DB级别,只是你必须改变SQL查询它将工作。

的例子,

"SELECT * FROM <TABLE> where userId = '" + iv_userId + "' AND password = BINARY '" + iv_password + "'";

二进制关键字将区分大小写。

在不更改所查询列的排序规则的情况下执行区分大小写的字符串比较的最正确方法是显式地指定要与列进行比较的值的字符集和排序规则。

select * from `table` where `column` = convert('value' using utf8mb4) collate utf8mb4_bin;

为什么不使用binary呢?

使用binary操作符是不可取的,因为它比较的是编码字符串的实际字节数。如果比较使用不同字符集编码的两个字符串的实际字节,两个应该被认为相同的字符串可能不相等。例如,如果您有一个使用latin1字符集的列,并且您的服务器/会话字符集是utf8mb4,那么当您将该列与包含重音的字符串(如'café')进行比较时,它将不匹配包含相同字符串的行!这是因为在latin1中é被编码为字节0xE9,但在utf8中它是两个字节:0xC3A9

为什么使用convertcollate?

排序规则必须与字符集匹配。因此,如果你的服务器或会话设置为使用latin1字符集,你必须使用collate latin1_bin,但如果你的字符集是utf8mb4,你必须使用collate utf8mb4_bin。因此,最健壮的解决方案是始终将值转换为最灵活的字符集,并对该字符集使用二进制排序规则。

为什么将convertcollate应用于值而不是列?

当您在进行比较之前对列应用任何转换函数时,如果该列存在索引,则查询引擎将无法使用该索引,这可能会极大地降低查询速度。因此,在可能的情况下转换值总是更好。当在两个字符串值之间执行比较,并且其中一个具有显式指定的排序规则时,查询引擎将使用显式排序规则,而不管它应用于哪个值。

口音的敏感性

值得注意的是,MySql不仅对使用_ci排序规则的列不区分大小写(通常是默认的),而且对口音也不区分。这意味着'é' = 'e'.;使用二进制排序规则(或binary操作符)将使字符串比较区分重音和大小写。

utf8mb4是什么?

MySql中的utf8字符集是utf8mb3的别名,它一直是在最近版本中已弃用,因为它不支持4字节字符(这对于编码🐈这样的字符串很重要)。如果你想在MySql中使用UTF8字符编码,那么你应该使用utf8mb4字符集。

对于那些希望使用RLIKEREGEXP与正则表达式进行区分大小写的比较的人来说,你可以像这样使用匹配类型cREGEXP_LIKE():

SELECT * FROM `table` WHERE REGEXP_LIKE(`column`, 'value', 'c');