【问题标题】:MySQL/MariaDB unable to handle unique keys with when using utf8mb4MySQL/MariaDB 在使用 utf8mb4 时无法处理唯一键
【发布时间】:2017-11-05 08:53:08
【问题描述】:

我们有带有 utf8mb4 字符串的 MySQL 表:

CREATE TABLE `test` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`code` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `test_code_unique` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

当插入特殊字符时,似乎出现了错误的转换:

mysql> insert into `test` (`code`, `name`) values ('munster', 'Munster');


mysql> insert into `test` (`code`, `name`) values ('münster', 'Münster');
ERROR 1062 (23000): Duplicate entry 'münster' for key 'test_code_unique'


mysql> SELECT * FROM test WHERE code='münster';
+----+---------+---------+
| id | name    | code    |
+----+---------+---------+
|  1 | Munster | munster |
+----+---------+---------+
1 row in set (0.00 sec)



mysql> SELECT * FROM test WHERE code='munster';
+----+---------+---------+
| id | name    | code    |
+----+---------+---------+
|  1 | Munster | munster |
+----+---------+---------+
1 row in set (0.00 sec)

如果删除了唯一键,则第二次插入有效,但即使查询不同,搜索也会返回 2 行:

mysql> drop table test;


CREATE TABLE `test` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`code` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;


mysql> insert into `test` (`code`, `name`) values ('munster', 'Munster');


mysql> insert into `test` (`code`, `name`) values ('münster', 'Münster');


mysql> SELECT * FROM test WHERE code='münster';
+----+----------+----------+
| id | name     | code     |
+----+----------+----------+
|  1 | Munster  | munster  |
|  2 | Münster  | münster  |
+----+----------+----------+
2 rows in set (0.00 sec)


mysql> SELECT * FROM test WHERE code='munster';
+----+----------+----------+
| id | name     | code     |
+----+----------+----------+
|  1 | Munster  | munster  |
|  2 | Münster  | münster  |
+----+----------+----------+
2 rows in set (0.00 sec)

这已经在 MySQL 5.7 和 MariaDB 10.2 上进行了测试,它们都给出了相同的结果。

可能出了什么问题?

【问题讨论】:

    标签: mysql utf-8 character-encoding mariadb


    【解决方案1】:

    这个看似神秘的问题的原因是您正在使用utf8mb4_unicode_ci 排序规则,并且该排序规则有意忽略了重音字符与非重音字符之间的差异。见:https://dev.mysql.com/doc/refman/5.7/en/charset-general.html

    要解决此问题,请将code 列上的排序规则更改为utf8mb4_bin,这将区分重音字符和非重音字符以及大小写。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-04
      • 1970-01-01
      • 2015-03-03
      • 2021-08-05
      • 2018-05-13
      • 2015-04-16
      • 1970-01-01
      相关资源
      最近更新 更多