近期,一直在忙着写一个小小的个人博客项目,在实现 “全局搜索” 功能时,发现 mysql 模糊查询语句有点儿神奇(本小白刚刚步入编程阶段,所以可能让大家见笑了,哈哈哈),有时候 mysql 模糊查询语句区分大小写,有时候 mysql 查询语句又不区分度大小写,于是,做了很多次实验,得出以下结论(可能有不对的地方,欢迎大佬们可以指出我的不足,也欢迎小伙伴们可以一起讨论问题!)
先来介绍一下 COLLATE,COLLATE 通常是和数据编码(CHARSET)相关的,一般来说每种 CHARSET 都有多种它所支持的 COLLATE,并且每种 CHARSET 都指定一种 COLLATE 为默认值。例如 latin1 编码的默认 COLLATE 为 latin1_swedish_ci,gbk 编码的默认 COLLATE 为 gbk_chinese_ci,utf8mb4 编码的默认值为 utf8mb4_general_ci:
CHSRSET | COLLATE |
---|---|
latin1 | latin1_swedish_ci |
gbk | gbk_chinese_ci |
utf8mb4 | utf8mb4_general_ci |
utf8 | utf8_bin |
有兴趣的小伙伴,可以在 navicate 等数据库可视化工具中,自己尝试一下:
注意:mysql 中有 utf8 和 utf8mb4 两种编码,但是 mysql 中的 utf8 最多只能支持 3bytes 长度的字符编码,所以,建议大家还是选择 utf8mb4 编码格式;
解决方法一
如图所示,为了便于区分,让小伙伴们更好地理解,在此,本小白建立了两个一模一样的数据库,其中一个采用 utf8 编码格式,另外一个采用 utf8mb4 格式:
区分大小写
建表语句也采用 utf8 编码格式:
建表语句
- blog_test : utf8 编码格式
SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_blog
-- ----------------------------
DROP TABLE IF EXISTS `t_blog`;
CREATE TABLE `t_blog` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`appreciation` bit(1) NOT NULL,
`comment_tabled` bit(1) NOT NULL,
`content` longtext CHARACTER SET utf8 COLLATE utf8_bin NULL,
`create_time` datetime(0) NULL DEFAULT NULL,
`first_picture` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`flag` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`published` bit(1) NOT NULL,
`recommend` bit(1) NOT NULL,
`share_statement` bit(1) NOT NULL,
`title` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`update_time` datetime(0) NULL DEFAULT NULL,
`views` int(11) NULL DEFAULT NULL,
`type_id` bigint(20) NULL DEFAULT NULL,
`user_id` bigint(20) NULL DEFAULT NULL,
`description` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `FK292449gwg5yf7ocdlmswv9w4j`(`type_id`) USING BTREE,
INDEX `FK8ky5rrsxh01nkhctmo7d48p82`(`user_id`) USING BTREE,
CONSTRAINT `FK292449gwg5yf7ocdlmswv9w4j` FOREIGN KEY (`type_id`) REFERENCES `t_type` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `FK8ky5rrsxh01nkhctmo7d48p82` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
数据库内容
查询结果
-
select * from
t_blog
wheretitle
like ‘%html%’; -
select * from
t_blog
wheretitle
like ‘%HTML%’;
结论:
mysql 采用 utf8 编码格式,模糊查询区分大小写
不区分大小写
建表语句
建表语句也采用 utf8mb4 编码格式:
- blog_test2 : utf8mb4 编码格式
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_blog
-- ----------------------------
DROP TABLE IF EXISTS `t_blog`;
CREATE TABLE `t_blog` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`appreciation` bit(1) NOT NULL,
`comment_tabled` bit(1) NOT NULL,
`content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL,
`create_time` datetime(0) NULL DEFAULT NULL,
`first_picture` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`flag` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`published` bit(1) NOT NULL,
`recommend` bit(1) NOT NULL,
`share_statement` bit(1) NOT NULL,
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`update_time` datetime(0) NULL DEFAULT NULL,
`views` int(11) NULL DEFAULT NULL,
`type_id` bigint(20) NULL DEFAULT NULL,
`user_id` bigint(20) NULL DEFAULT NULL,
`description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `FK292449gwg5yf7ocdlmswv9w4j`(`type_id`) USING BTREE,
INDEX `FK8ky5rrsxh01nkhctmo7d48p82`(`user_id`) USING BTREE,
CONSTRAINT `FK292449gwg5yf7ocdlmswv9w4j` FOREIGN KEY (`type_id`) REFERENCES `t_type` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `FK8ky5rrsxh01nkhctmo7d48p82` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
数据库内容
查询结果
-
select * from
t_blog
wheretitle
like ‘%html%’; -
select * from
t_blog
wheretitle
like ‘%HTML%’;
结论
mysql 采用 utf8mb4 编码格式,模糊查询不区分大小写
解决方法二
区分大小写
方法
单独指定所需字段(比如,在此处 我所需要区分大小写的字段为表 ‘t_blog’ 中的 ‘title’ 字段)为 ‘utf8’ 编码格式,COLLATE 为 “utf8_bin”;
alter table t_blog CHANGE `title` `title` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL;
结论
-
select * from
t_blog
wheretitle
like ‘%HTML%’; -
select * from
t_blog
wheretitle
like ‘%html%’;由上述执行结果可以看出,此方法可以使模糊查询语句区分大小写;
不区分大小写
方法
单独指定所需字段(比如,在此处 我所需要不区分大小写的字段为表 ‘t_blog’ 中的 ‘title’ 字段)为 ‘utf8mb4’ 编码格式,COLLATE 为 “utf8mb4_bin”:
alter table t_blog CHANGE `title` `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL;
结论
- select * from
t_blog
wheretitle
like ‘%HTML%’;
-
select * from
t_blog
wheretitle
like ‘%html%’;
由上述执行结果可以看出,此方法可以使模糊查询语句不区分大小写;
解决办法三
区分大小写
方法
-
如图所示,当前 ‘t_blog’ 表格的 ‘title’ 字段的 COLLATE 为 ‘utf8mb4_general_ci’ , 不区分大小写
-
修改字段为 BINARY:
alter table t_blog CHANGE `title` `title` varchar(255) BINARY NULL DEFAULT NULL;
alter table `t_blog` modify column `title` varchar(255) BINARY NULL DEFAULT NULL;
两种修改方式选择一种既可
结论
-
select * from
t_blog
wheretitle
like ‘%HTML%’; -
select * from
t_blog
wheretitle
like ‘%html%’;由上述执行结果可以看出,修改字段为 BINARY,可以使模糊查询语句区分大小写;
解决办法四
区分大小写
方法
-
如图所示,当前 ‘t_blog’ 表格的 ‘title’ 字段的 COLLATE 为 ‘utf8mb4_general_ci’ , 不区分大小写
-
查询语句字段前面加 BINARY:
select * from `t_blog` where BINARY `title` like '%html%';
结论
-
select * from
t_blog
wheretitle
like ‘%html%’; -
select * from
t_blog
where BINARYtitle
like ‘%html%’;
由上述执行结果可以看出,在查询语句字段前面加 BINARY,可以使模糊查询语句区分大小写。
解决办法五(特别特别不推荐,尽量不要使用)
找到 mysql 相应版本下的 my.ini 文件,本小白对应的 8.0.17 版本;
在文件最后一行加上下面一句话:
lower_case_table_names=1
注意:0:区分大小写,1:不区分大小写
重启 mysql
本小白还有很多地方讲解的不够清楚明了,还请各位大佬指教!想更深入了解的可以参考大佬的博客(膜拜膜拜)mysql 区分大小写