mysql踩坑记录
mysql使用 = 精确查询时会忽略尾部空格, 不区分大小写。
例如: 'AAA' = 'AAA ' , 'aaa' = 'aAa'
对于问题一
为什么会这样?
MySQL 在进行字符串比较时遵循以下规则:
- 对于 CHAR 类型字段,存储时会自动删除尾随空格。
- 对于 VARCHAR 类型字段,在比较时会忽略尾随空格。
如何避免这个问题?
-
使用二进制比较:可以使用BINARY关键字进行严格比较。
SELECT name, LENGTH(name
) FROM users WHERE BINARY name = 'AAA'; -
使用LIKE进行精确匹配:
SELECT name, LENGTH(name
) FROM users WHERE name LIKE 'AAA'; -
显式地处理空格:可以通过TRIM函数显式去掉空格后再进行比较
SELECT name, LENGTH(name
) FROM users WHERE TRIM(name) = 'AAA';
对于问题二
-
使用mysql 的BINARY 关键字使搜索区分大小写。
-
修改字段的排序规则
字符集是一套符号和编码,校对规则是在字符集内用于比较字符的一套规则。 一般而言,校对规则以其相关的字符集名开始,通常包括一个语言名,并且以_ci(大小写不敏感)、_cs(大小写敏感)或_bin(二元)结束 。
比如 utf8字符集,,如下表:
1)utf8_bin:utf8_bin将字符串中的每一个字符用二进制数据存储,区分大小写。
2)utf8_general_ci:utf8_genera_ci不区分大小写,ci为case insensitive的缩写,即大小写不敏感。
3)utf8_general_cs:utf8_general_cs区分大小写,cs为case sensitive的缩写,即大小写敏感。
注:我本机使用5.7 版本不支持 utf8_general_cs 字符集,创建报错。
总结
实测结果:
以utf8mb4字符集为例
排序规则后缀对于大小写和尾部空格的影响
- utf8mb4_bin 字母大小写敏感,忽略尾部空格
- utf8mb4_0900_as_cs 字母大小写敏感,不忽略尾部空格
- utf8mb4_0900_ai_ci 不区分字母大小写,不忽略尾部空格
- utf8mb4_general_ci 不区分字母大小写,忽略尾部空格