问题
假设在address
表中存在如下一条记录,注意圆括号为英文的(
和)
id | details |
---|---|
1 | xx省yy市zz区某某街道(12)号 |
当使用如下语句查询某个地址的记录是否存在,注意这里使用中文的(
和)
SELECT * FROM address WHERE details = 'xx省yy市zz区某某街道(12)号'
结果竟然能够查到匹配的记录。
分析
因为中文符号和英文符号是和字符集相关的,同时mysql的配置中和字符集比较和排序相关的是collation
, 检查当前系统中的collation
配置`
show variables like 'colla%'
Variable_name | Value |
---|---|
collation_connection | utf8mb4_general_ci |
collation_database | utf8mb4_unicode_ci |
collation_server | utf8mb4_unicode_ci |
这里可以看到collation_connection
的配置和collation_database
的配置不一致
- 尝试将
collation_connection
和collation_database
都设置为utf8mb4_general_ci
, 结果中文符号的查询按预期不能匹配到记录 - 尝试将
collation_connection
和collation_database
都设置为utf8mb4_general_ci
, 结果中文符号的查询按预期不能匹配到记录
可以看到当connection和database的都一致的时候我们能够获得预期结果,问题就是两者不一致.
检查数据库的my.cnf中发现有这么两行:
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
这里可以看到collation-server=utf8mb4_unicode_ci
这里设置了collation_server
但是没有设置collation_connection
解决办法
- 移除掉
collation-server=utf8mb4_unicode_ci
这一行 - 转换数据库层级的配置
set collation_database=utf8mb4_general_ci
- 转换表层级的配置
alter table OrderShippingItem convert to character set utf8mb4 collate utf8mb4_general_ci;
4.重启mysqld