如何使MySQL字符串查询区分大小写?
#1 楼
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
如果要始终以区分大小写的方式处理列,请使用区分大小写或二进制排序规则对其进行声明。
评论
关于如何在phpmyadmin中执行此操作的任何提示?
–StevenB
2011年4月12日,0:44
@StevenB:单击列的“编辑”按钮,然后设置排序规则-> i.imgur.com/7SoEw.png
–苦力
2011年4月12日,0:50
@BT要使utf8列区分大小写,您可以使用bin排序规则,例如:SELECT'email'COLLATE utf8_bin ='Email'
–piotrekkr
13年4月23日在11:43
@drudge您如何用区分大小写的排序规则声明一列?
– Stephane
14-10-11在11:47
@StephaneEybert,如果您正在寻找区分大小写的方法,我很幸运在ut8表中的字段中使用varbinary而不是varchar。高温超导
– Andrew T
2015年1月5日,19:54
#2 楼
好消息是,如果您需要进行区分大小写的查询,则很容易做到:SELECT * FROM `table` WHERE BINARY `column` = 'value'
评论
这正是我想要的。如果可以的话,我会更高。但有一个问题,这对性能有什么影响?我仅在有限的报告内容上使用它,因此对我而言这并不重要,但我很好奇。
– adjwilli
2012年8月25日19:13
为什么这不是答案?这正是我所需要的。
– Art Geigel
13年7月26日在5:27
@adjwilli如果该列是索引的一部分,则依赖该索引的查询将遭受性能下降。为了保持性能,您需要实际更改表。
–dshin
2013年9月19日18:50
这对于包含相同字符且具有不同表示形式的UTF-8字符串有什么作用,例如使用组合字符来添加变音符号?可以将这些UTF-8字符串视为相等:使用utf8的convert(char(0x65,0xcc,0x88))(即,加上¨的e)和使用utf8的convert(char(0xc3,0xab))(即,ë),但添加BINARY将使它们不相等。
–mvds
15年6月8日在15:09
作为一个性能示例:我的查询从3,5毫秒(可忽略不计)传递到1.570毫秒(这大约是一个半秒),查询的表包含约180万行。
–LluísSuñol
19年2月25日在14:30
#3 楼
克雷格·怀特(Craig White)发布的答案对性能造成了很大的影响SELECT * FROM `table` WHERE BINARY `column` = 'value'
,因为它不使用索引。因此,您需要更改表排序规则,例如在这里提到https://dev.mysql.com/doc/refman/5.7/en/case-sensitiveivity.html。
OR
最简单的解决方法是,应该使用值的BINARY。
评论
在10.3.22-MariaDB上,这似乎不区分大小写(使用libmysql-5.6.43)
–user10398534
4月21日19:48
我使用了克雷格·怀特(Craig White)的解决方案一年,但是在抱怨了一些页面加载后,我进行了更深入的研究,提出了Nitesh建议的更改,查询时间从2.5秒变为0.15秒。当Binary在Where之前时,它没有使用索引。将Binary移动到after之后使用索引的位置。谢谢!
– Michaelf
9月20日12:33
好主意尼特什!这应该是票数最高的答案
–billynoah
11月18日16:57
#4 楼
而不是使用=运算符,您可能想使用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'
评论
在10.3.22-MariaDB上,这似乎不区分大小写(使用libmysql-5.6.43)
–user10398534
4月21日19:48
#5 楼
在不更改要查询的列的排序规则的情况下执行区分大小写的字符串比较的最正确方法是为要比较的列的值显式指定一个字符集和排序规则。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
是什么?MySql中的
utf8
字符集是一个utf8mb3
的别名,由于它不支持4字节字符(在对诸如🐈之类的字符串进行编码时很重要),因此在最近版本中已弃用。如果希望对MySql使用UTF8字符编码,则应使用utf8mb4
字符集。#6 楼
要在使用BINARY之前先使用索引,如果表很大,可以执行以下操作。SELECT
*
FROM
(SELECT * FROM `table` WHERE `column` = 'value') as firstresult
WHERE
BINARY `column` = 'value'
子查询将导致非常小的情况-不区分大小写的子集,然后选择唯一的区分大小写的匹配项。
评论
值得一提的是,以上内容仅会根据您的数据提供帮助-不区分大小写的搜索可能会返回相当大的数据子集。
– BrynJ
17年8月10日在11:19
#7 楼
以下是等于或高于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/zh-CN/case-sensitivity.html也有一个“ latin1_bin”。
mysql启动不接受“ utf8_general_cs” 。 (我将“ _cs”读为“区分大小写”-???)。
#8 楼
您可以使用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 |
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
评论
在10.3.22-MariaDB上,这似乎不区分大小写(使用libmysql-5.6.43)
–user10398534
4月21日19:49
#9 楼
太好了!我与您分享了比较密码功能的代码:
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;
评论
需要添加声明pSuccess BINARY;一开始
–地名
18年8月5日在8:11
#10 楼
无需在数据库级别上进行任何更改,只需更改SQL Query即可。示例-
"SELECT * FROM <TABLE> where userId = '" + iv_userId + "' AND password = BINARY '" + iv_password + "'";
二进制关键字将使区分大小写。
#11 楼
mysql默认情况下不区分大小写,请尝试将语言排序规则更改为latin1_general_cs
评论
dev.mysql.com/doc/refman/5.0/en/charset-binary-op.html请注意,BINARY与区分大小写的比较不同:select'à'like'a'//返回true选择'à'like BINARY'a'//返回false!选择'à'像'a'那样COLLATE latin1_general_cs //返回true因此,将BINARY用于区分大小写的比较的建议是不正确的。
@cquezel:所以,你是说[选择BINARY'a'之类的'à']应该返回true?无论如何,这与区分大小写的比较有什么关系?
@FranciscoZarabozo下面的一些人建议使用BINARY比较来进行区分大小写的比较。我只是指出,在其他语言中,这可能无法按预期方式工作,因为BINARY与区分大小写的字母不同。
@cquezel我认为'à'与'a'是不同的字母。因此,无论哪种情况,两者之间的比较确实应该是错误的。