【发布时间】:2017-03-21 04:02:59
【问题描述】:
我正在尝试将数据库转换为使用 utf8mb4 而不是 utf8。除了一张桌子,一切都很好:
CREATE TABLE `search_terms` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`search_term` varchar(128) NOT NULL,
`time_added` timestamp NULL DEFAULT NULL,
`count` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `search_term` (`search_term`),
KEY `search_term_count` (`count`)
) ENGINE=InnoDB AUTO_INCREMENT=198981 DEFAULT CHARSET=utf8;
基本上,它所做的只是在每次有人在表单中搜索某些内容时保存一个条目,这样我们就可以跟踪搜索次数,非常简单。
search_term 上有一个唯一索引,因为我们希望每个搜索词只有一行,而是增加计数值。
但是,在转换为 utf8mb4 时,我遇到了重复的输入错误。这是我正在运行的命令:
ALTER TABLE `search_terms` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
查看数据库,我可以看到如下各种示例:
fm2012
fm2012
fm2012
在当前的 utf8 字符集中,这些都被视为唯一并存在于数据库中,而 search_term 上的唯一索引没有问题。
但是当转换为 utf8mb4 时,它们现在被认为是相等的,并且由于该索引而引发错误。
我可以很容易地弄清楚如何将它们合并在一起,但我担心这可能是更大潜在问题的征兆。我不太确定这是怎么发生的,或者可能产生什么后果,所以我的问题有点含糊:
- 为什么 utf8mb4 将这些与 utf8 区别对待?
- 可能的后果是什么?
- 有没有什么办法可以进行转换,这样“fm2012”之类的东西就不会出现在我的数据库中,我只有“fm2012”(我也在使用 Laravel 5.1)
【问题讨论】:
-
老实说,这看起来更像是 UTF-32 和 UTF-16。转换这样做很奇怪。这会发生在普通测试表上吗?
-
能否粘贴您的错误信息?
-
转换前的排序规则是什么?这些真的是您的示例字符串“fm2012”中的空格吗?你能把十六进制转储给我们吗?
-
@NishantNair 这是一个简单的“重复条目 'fm2012' 键 'seach_term'”
-
@Beat 它是“utf8_general_ci”,据我所知,它不是空格。它看起来与这个 SO 问题中的完全一样。我不确定你所说的十六进制转储是什么意思
标签: php mysql utf-8 unique-index utf8mb4