我有一个函数,返回大小写混合的五个字符。如果我对此字符串进行查询,则无论大小写都将返回该值。
如何使MySQL字符串查询区分大小写?
我有一个函数,返回大小写混合的五个字符。如果我对此字符串进行查询,则无论大小写都将返回该值。
如何使MySQL字符串查询区分大小写?
Answers:
http://dev.mysql.com/doc/refman/5.0/zh-CN/case-sensitiveivity.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
如果希望始终以区分大小写的方式对待列,请使用区分大小写或二进制排序规则进行声明。
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
会让他们不等。
Craig White发表的答案,对性能有很大的影响
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秒)
在不更改要查询的列的排序规则的情况下执行区分大小写的字符串比较的最正确方法是为要比较的列的值显式指定一个字符集和排序规则。
select * from `table` where `column` = convert('value' using utf8mb4) collate utf8mb4_bin;
binary
?不建议使用binary
运算符,因为它会比较编码字符串的实际字节。如果比较使用不同字符集编码的两个字符串的实际字节,则两个应该被视为相同的字符串可能不相等。例如,如果您有一列使用latin1
字符集,而服务器/会话字符集是utf8mb4
,那么当您将该列与包含重音符号的字符串(例如“café”)进行比较时,将不会匹配包含该字符串的行!这是因为latin1
é编码为字节,0xE9
但utf8
其中有两个字节:0xC3A9
。
convert
以及collate
?排序规则必须与字符集匹配。因此,如果服务器或会话设置为使用latin1
字符集,则必须使用,collate latin1_bin
但是如果字符集是utf8mb4
,则必须使用collate utf8mb4_bin
。因此,最可靠的解决方案是始终将值转换为最灵活的字符集,并对该字符集使用二进制排序规则。
convert
和collate
应用于值而不是列?如果在进行比较之前将任何转换功能应用于列,则会阻止查询引擎使用索引(如果该列存在索引),这可能会大大降低查询速度。因此,最好总是尽可能地转换值。当在两个字符串值之间执行比较并且其中一个具有显式指定的排序规则时,查询引擎将使用该显式排序规则,而不管它应用于哪个值。
重要的是要注意,MySql不仅对使用_ci
排序规则的列不区分大小写(通常是默认设置),而且对重音不敏感。这意味着'é' = 'e'
。使用二进制排序规则(或binary
运算符)将使字符串比较区分重音和区分大小写。
utf8mb4
啊utf8
MySql中的字符集是一个别名,在最近的版本中utf8mb3
已弃用该别名,因为它不支持4字节字符(这对于编码诸如🐈之类的字符串很重要)。如果希望对MySql 使用UTF8字符编码,则应使用utf8mb4
字符集。
以下是等于或高于5.5的MySQL版本。
添加到/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”。
mysql启动不接受“ utf8_general_cs”。(我将“ _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;
在开始时添加