摘要:在MySQL中,设置字符集和排序规则,在查询时区分字母大小写,utf8mb4支持emoji表情,而utf8不支持。
问题综述
在工作中,设置的一些唯一标志字符串和登录密码都是区分大小写的,但是,在从MySQL数据库查询的时候,却遇到了不区分英文字母大小写的尴尬糗事,好不惊讶!赶快科普一番,发现MySQL区分大小写取决于数据库的排序规则(collation),今天在这里总结一下。
在MySQL中,字符集和排序规则是区分开来的,你需要单独设置字符集和排序规则。当然MySQL字符集和排序规则也是相关联的。除非特殊需求,只要设置其一即可,例如,设置字符集,即设置了默认的排序规则。一般创建数据库都推荐使用 utf8mb4 字符集,下面列出UTF8和utf8mb4的排序规则:
MySQL UTF8 常用字符排序规则
排序规则 | 描述 |
---|---|
utf8_general_ci | 不区分大小写,默认排序规则 |
utf8_general_cs | 区分大小写 |
utf8_bin | 区分大小写,字符串每个字符串用二进制数据编译存储,且支持存储二进制数据 |
MySQL utf8mb4 常用字符排序规则
排序规则 | 描述 |
---|---|
utf8mb4_bin | 区分大小写,将字符串每个字符用二进制数据编译存储,区分e和é这类字符 |
utf8mb4_general_ci | ci即case insensitive,不区分大小写,不区分e和é这类字符,默认排序规则 |
utf8mb4_unicode_ci | 不区分大小写,能够在各种语言之间精确排序,不区分e和é这类字符 |
utf8mb4_general_cs | 区分大小写,不区分e和é这类字符 |
utf8mb4 和 utf8的区别
官方对utf8mb4 和 utf8的定义如下:
-
utf8mb4: A UTF-8 encoding of the Unicode character set using one to four bytes per character.
-
utf8mb3: A UTF-8 encoding of the Unicode character set using one to three bytes per character.
-
utf8: An alias for utf8mb3.
Note
The utf8mb3 character set is deprecated and you should expect it to be removed in a future MySQL release. Please use utf8mb4 instead. utf8 is currently an alias for utf8mb3, but it is now deprecated as such, and utf8 is expected subsequently to become a reference to utf8mb4. Beginning with MySQL 8.0.28, utf8mb3 is also displayed in place of utf8 in columns of Information Schema tables, and in the output of SQL SHOW statements.
To avoid ambiguity about the meaning of utf8, consider specifying utf8mb4 explicitly for character set references.
如上英文简单概括如下:
(1)utf8mb4 是真正的 UTF-8。
(2)utf8 是一种专属的编码,它能够编码的 Unicode 字符并不多。
(3)预计uft8将指代utf8mb4。
由此可见,推荐使用字符集utf8mb4指定字符集,而非使用模棱两可的utf8。另外,utf8mb4支持emoji表情,而utf8不支持。
问题复现
如下两个查询条件在根据用户密码查询user表的数据时,结果一致,即不区分字母大小写:
SELECT * FROM `user` WHERE password = 'M.77720';
SELECT * FROM `user` WHERE password = 'm.77720';
问题分析
执行show full columns
命令查看表结构,发现结果集中 collation 属性存在 utf8_general_ci,脚本和结果集截图如下所示:
show full COLUMNS FROM user;
查看排序规则
还可以使用如下命令查看表的排序规则:
show table status from schema_name like '%table_name%';
此命令支持表名模糊匹配。一般MySQL建schema和table的强制规范如下:
- 创建schema时务必显式指定字符集,而且字符集只能是utf8mb4;
- 表的字符集建议使用utf8mb4;
- 表的排序规则需要区分大小写。
故由截图可知,我们创建的表结构,使用了错误的字符集和错误的排序规则,需要同时改掉。也可以使用如下命令查看表的字符集:
SHOW CREATE TABLE table_name;
binary 临时解决方案
我们用binary关键字来强制区分字母大小写,改写SQL脚本如下:
SELECT * FROM `user` WHERE binary password = 'M.77720';
SELECT * FROM `user` WHERE binary password = 'm.77720';
则执行如上查询脚本后,可以看到结果集不一致,故问题成功解决。瑕疵是这是一种治标不治本的策略。
MySQL修改表的字符集和修改字段的字符集
请移步《MySQL修改表和字段的字符集和排序规则》。
结束语
MySQL创建schema和table的时候,请设置字符集为uftmb8,排序规则请指定为utf8mb4_bin,以在查询时区分字母大小写,插入时支持emoji等特殊字符