环境:MySQL 5.7
现象
假设有一张表,结构如下:
1 2 3
| CREATE TABLE `test` ( `a` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
然后插入两条数据(一条是中文括号,一条是英文括号):
1 2
| INSERT INTO `test` (`a`) VALUES ('(甲)'); INSERT INTO `test` (`a`) VALUES ('(甲)');
|
然后大家觉得下面的语句结果如何?
1
| SELECT * FROM test GROUP BY a
|
是不是觉得应该有两条,像下面的一样:
1 2 3 4 5 6 7 8
| mysql> SELECT * FROM test; +-----------+ | a | +-----------+ | (甲) | | (甲) | +-----------+ 2 rows in set (0.01 sec)
|
但实际上只有一条:
1 2 3 4 5 6
| +-----------+ | a | +-----------+ | (甲) | +-----------+ 1 row in set (0.01 sec)
|
也就是说,对于 MySQL 来说,"(甲)"
和
"(甲)"
是一样的。
但是我们明确知道,这里其中一个是中文的括号,另一个是英文的括号。
原因
在 utf8_unicode_ci
下,MySQL
在比较的时候,"("
跟 "("
是一样的:
参考链接:https://stackoverflow.com/a/6602382/6048782
1 2 3 4 5 6 7
| mysql> select _utf8"(" collate utf8_unicode_ci = _utf8"(" collate utf8_unicode_ci; +-----------------------------------------------------------------------+ | _utf8"(" collate utf8_unicode_ci = _utf8"(" collate utf8_unicode_ci | +-----------------------------------------------------------------------+ | 1 | +-----------------------------------------------------------------------+ 1 row in set (0.06 sec)
|
解决办法
使用 utf8mb4 字符集,因为:
1 2 3 4 5 6 7
| mysql> select _utf8mb4"(" collate utf8mb4_general_ci = _utf8mb4"(" collate utf8mb4_general_ci; +-----------------------------------------------------------------------------------+ | _utf8mb4"(" collate utf8mb4_general_ci = _utf8mb4"(" collate utf8mb4_general_ci | +-----------------------------------------------------------------------------------+ | 0 | +-----------------------------------------------------------------------------------+ 1 row in set (0.01 sec)
|
也就是说,在 utf8mb4_general_ci
这种字符集下,MySQL
在进行比较的时候才能正确判断中英文括号。
修改字段的 SQL 语句
1
| alter table tbl modify col varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
|