mysql查询时字符串区分大小写问题

170 阅读3分钟

mysql默认情况下查询语句的where条件是不区分大小写的。

建表语句

CREATE TABLE `test_users` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL DEFAULT '' COMMENT '姓名',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

初始化语句

INSERT INTO `test_users` (`id`, `name`)
VALUES
	(1, 'Abc'),
	(2, 'abc'),
	(3, 'sss');

默认不区分大小写

select * from test_users where  name = "abc";

输出结果

idname
1Abc
2abc

索引情况

explain select * from test_users where name = "abc";

索引结果:

idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEtest_usersNULLrefidx_nameidx_name122const2100Using index

命中了索引index_name,并且type = const

区分大小写的方法

区分大小写的方法有3种:

  • 字段前添加关键字: binary
  • 建表时字段加入关键字:binary
  • 修改字段字符集:

方案一:查询条件字段前添加关键字:binary

查询语句

select * from test_users where binary name = "abc";

输出结果

idname
2abc

查询语句索引情况

explain select * from test_users where binary name = "abc";

输出结果:

idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEtest_usersNULLindexNULLidx_name122NULL3100Using where; Using index

可以看出来命中了索引 idx_name,并且 type = index

方案二:建表时字段加入关键字:binary

CREATE TABLE `test_users` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) binary NOT NULL DEFAULT '' COMMENT '姓名',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

查询语句

select * from test_users where name = "abc";

输出结果

idname
2abc

查询语句索引情况

explain select * from test_users where name = "abc";

输出结果:

idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEtest_usersNULLrefidx_nameidx_name122const1100Using index

可以看出命中了 idx_name索引,并且type = ref

方案三:修改字段的字符序(collation)

字符集(character set)和字符序(collation)是两个东西, 一个字符集对应1个或者多个字符序。

可以通过SHOW COLLATION查看数据库支持的字符序,通过SHOW CHARACTER SET字符集

SHOW COLLATION where collation like 'utf8mb4_%'命令

CollationCharsetIdDefaultCompiledSortlen
utf8mb4_general_ciutf8mb445YesYes1
utf8mb4_binutf8mb446Yes1
utf8mb4_unicode_ciutf8mb4224Yes8
utf8mb4_icelandic_ciutf8mb4225Yes8
utf8mb4_latvian_ciutf8mb4226Yes8
utf8mb4_romanian_ciutf8mb4227Yes8
utf8mb4_slovenian_ciutf8mb4228Yes8
utf8mb4_polish_ciutf8mb4229Yes8
utf8mb4_estonian_ciutf8mb4230Yes8
utf8mb4_spanish_ciutf8mb4231Yes8
utf8mb4_swedish_ciutf8mb4232Yes8
utf8mb4_turkish_ciutf8mb4233Yes8
utf8mb4_czech_ciutf8mb4234Yes8
utf8mb4_danish_ciutf8mb4235Yes8
utf8mb4_lithuanian_ciutf8mb4236Yes8
utf8mb4_slovak_ciutf8mb4237Yes8
utf8mb4_spanish2_ciutf8mb4238Yes8
utf8mb4_roman_ciutf8mb4239Yes8
utf8mb4_persian_ciutf8mb4240Yes8
utf8mb4_esperanto_ciutf8mb4241Yes8
utf8mb4_hungarian_ciutf8mb4242Yes8
utf8mb4_sinhala_ciutf8mb4243Yes8
utf8mb4_german2_ciutf8mb4244Yes8
utf8mb4_croatian_ciutf8mb4245Yes8
utf8mb4_unicode_520_ciutf8mb4246Yes8
utf8mb4_vietnamese_ciutf8mb4247Yes8

常用的字符序:

  • utf8_general_ci & utf8mb4_general_ci: 不区分大小写
  • utf8_bin & utf8mb4_bin: 区分大小写

建表语句:

CREATE TABLE `test_users3` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '姓名',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

查询语句:

select * from test_users where name = "abc";

输出结果

idname
2abc

查询语句索引情况

explain select * from test_users where name = "abc";

输出结果:

idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEtest_usersNULLindexNULLidx_name122NULL3100Using where; Using index

命中了索引idx_name,并且 type = index