操作“=”的排序规则(utf8mb4_unicode_ci,EXPLICIT)和(utf8_general_ci,COERCIBLE)的非法混合
Posted
技术标签:
【中文标题】操作“=”的排序规则(utf8mb4_unicode_ci,EXPLICIT)和(utf8_general_ci,COERCIBLE)的非法混合【英文标题】:Illegal mix of collations (utf8mb4_unicode_ci,EXPLICIT) and (utf8_general_ci,COERCIBLE) for operation '=' 【发布时间】:2015-12-07 07:06:17 【问题描述】:好吧,我放弃了。我已经遇到此错误 2 天了,我需要帮助。
免责声明:我需要帮助来改进这个问题,并会尽力描述手头的问题,到目前为止我为解决这个问题所做的工作,并分享我读过的博客文章和文档寻找解决方案。
问题(也,在下面的上下文中提出):
所以问题是,为什么相同的查询在 从 Rails 而不是从 mysql 命令行运行?具体来说, "(utf8_general_ci,COERCIBLE)" 是从哪里来的?
问题:Autoresponder.find_by(keyword: '????')
失败并出现以下错误:
ActiveRecord::StatementInvalid: Mysql2::Error: Illegal mix of collations
(utf8mb4_unicode_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE)
for operation '=':
SELECT `autoresponders`.*
FROM `autoresponders`
WHERE `autoresponders`.`keyword` = '????'
LIMIT 1
Autoresponder
是具有keyword
属性的模型
我读到我需要指定我的排序规则。于是我测试了以下代码:
Autoresponder.where('keyword collate utf8mb4_unicode_ci = ?', '????')
并得到以下错误:
Illegal mix of collations
(utf8mb4_unicode_ci,EXPLICIT) and (utf8_general_ci,COERCIBLE)
for operation '=':
SELECT `autoresponders`.*
FROM `autoresponders`
WHERE (keyword collate utf8mb4_unicode_ci = '????')
所做的只是将排序规则从 IMPLICIT 更改为 EXPLICIT。
我尝试在 Sequel Pro 中运行查询并且它有效(使用和不使用 collate 关键字)。为了清楚起见,这里是查询:
SELECT `autoresponders`.*
FROM `autoresponders`
WHERE (keyword collate utf8mb4_unicode_ci = '????');
SELECT `autoresponders`.*
FROM `autoresponders`
WHERE (keyword = '???? ');
而且它有效!查询运行没有错误。我还运行了mysql
并且也能够在那里运行查询。但是当我将查询粘贴到mysql
命令行时,我注意到了一些事情。它自动使用字符的 Unicode 名称而不是实际字符。这是在 mysql 命令行中观察到的查询:
SELECT `autoresponders`.*
FROM `autoresponders`
WHERE (keyword collate utf8mb4_unicode_ci ='\U+1F615');
此查询有效。
所以问题是,为什么相同的查询在 Rails 中失败但在 Sequel Pro 中有效?具体来说,“(utf8_general_ci,COERCIBLE)”来自哪里,我该如何解决这个烂摊子?
我认为它可能来自 ActiveRecord,但在 Rails 控制台中运行 ActiveRecord::Base.connection.collation
会返回 utf8mb4_unicode_ci
这是我的 db 字符编码和排序规则变量(以及检索它们的查询)。
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
character_set_client utf8mb4
character_set_connection utf8mb4
character_set_database utf8mb4
character_set_filesystem binary
character_set_results utf8mb4
character_set_server latin1
character_set_system utf8
collation_connection utf8mb4_unicode_ci
collation_database utf8mb4_unicode_ci
collation_server latin1_swedish_ci
这是 Autorsponders 表的创建语法:
CREATE TABLE `autoresponders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`keyword` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT '',
`body` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`provisioned_number_id` int(11) DEFAULT NULL,
`outgoing_provisioned_number_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
上下文:Rails 4.0.13,Mysql 版本 5.6.22-1+deb.sury.org~precise+1-log
以下是我目前阅读的一些博客文章和 SO 文章: https://mathiasbynens.be/notes/mysql-utf8mb4
http://airbladesoftware.com/notes/fixing-mysql-illegal-mix-of-collations/
Is "SET CHARACTER SET utf8" necessary?
Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '='
Not case sensitive search with active record
https://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_collation_server
所有这些都让我创造了这个模因:
真诚的,
一个筋疲力尽的开发伙伴。
谢谢。
【问题讨论】:
错误信息暗示 MySQL 声称 client 正在提供 '????'作为 utf8 字符。 (应该声称是 utf8mb4。)我不知道 Ruby 和 ActiveRecord 的来龙去脉,但那是我要看的地方。 谢谢。我暂时停止处理这个问题。我可能会在几周后回到它。如果我弄清楚了,我会在这里记录答案。奇怪的是,它现在可以在开发(OS X)中工作,但不能在登台(Ubuntu)中工作 我最终通过使用 blob 而不是文本来“解决”这个问题。 另外,我们现在使用 postgres,它支持开箱即用的 4 字节字符。 【参考方案1】:我遇到了类似的问题并最终解决了。 一开始我的 MySQL conf 是:
character-set-server = utf8
collation-server = utf8_general_ci
有一天,我发现只有使用 utf8mb4 才能正确保存 emoji,所以我将指定列的字符集和排序规则更改如下:
`nickname` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
到目前为止,一切都很好,数据可以被java web应用程序正确保存和显示。
但是当我像这样查询数据时
SELECT * FROM table_name WHERE nickname LIKE '%?%';
错误引发。
最后我把 mysql conf 改成了
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
一切顺利。
还要确保SET NAMES utf8;
的任何调用都被删除或替换为SET NAMES utf8mb4
Here is a screenshot of mysql client, notice the nickname attribute
【讨论】:
如果你有一个 ruby on rails 应用程序,你可以通过在你的 database.yml 中添加以下内容来更改配置encoding: utf8mb4 charset: utf8mb4 collation: utf8mb4_unicode_ci
确保它在 3 行中(*** 打破了这些行)
请给我们看整个文件【参考方案2】:
我已经通过将列的排序规则更改为utf8mb4_unicode_ci
,从 phpMyAdmin 解决了这个问题。
【讨论】:
如果你能描述一下你做了什么,那就太好了。【参考方案3】:我在 where 语句之后添加了排序规则时遇到了同样的错误
SELECT * FROM chat_words where source ='forum';
将排序规则 (utf8mb4_unicode_ci,COERCIBLE) 和 (utf8mb4_general_ci,COERCIBLE) 的非法混合用于操作 '='
我后来改成
SELECT * FROM chat_words where source collate utf8mb4_unicode_ci ='forum';
这次运行没有错误
【讨论】:
【参考方案4】:当我将我的数据库复制到其他服务器时,我遇到了同样的问题。我已将排序规则更改为 utf8mb4_general_ci,它似乎工作正常。
【讨论】:
以上是关于操作“=”的排序规则(utf8mb4_unicode_ci,EXPLICIT)和(utf8_general_ci,COERCIBLE)的非法混合的主要内容,如果未能解决你的问题,请参考以下文章
utf8mb4_unicode_ci 在 PhpMyAdmin 中选择,但 WordPress 表使用 utf8mb4_unicode_520_ci 排序规则
排序规则将 utf8mb4_unicode_ci 更改为 utf8mb4_general_ci
MySql Unicode 排序规则 utf8mb4_german2_ci 未找到 *** 德语变音符号排序规则 ***
MySQL 数据库 - 将字符集和排序规则转换为 utf8mb4 和 utf8mb4_unicode_ci?