web-dev-qa-db-ja.com

操作 '='の照合(utf8mb4_unicode_ci、EXPLICIT)と(utf8_general_ci、COERCIBLE)の不正な組み合わせ

了解しました。あきらめます。このエラーが発生してから2日が経過しましたが、サポートが必要です。

免責事項:私はこの質問を改善するための助けが必要であり、目前の問題、問題に対処するためにこれまでに行ったことをうまく説明し、ブログ投稿と私が読んだドキュメントを共有するように努めます。解決。

質問(また、文脈で以下に尋ねられます):

したがって、問題は、mysqlコマンドラインからではなくRailsから実行した場合、同じクエリの動作が異なるのはなぜですか?具体的には、「(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でクエリを実行してみましたが、機能しました(collat​​eキーワードの有無にかかわらず)。わかりやすくするために、ここにクエリがあります。

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-collat​​ions/

"SET CHARACTER SET utf8"は必要ですか?

操作 '=' の照合(utf8_unicode_ci、IMPLICIT)と(utf8_general_ci、IMPLICIT)の不正な組み合わせ

アクティブレコードで大文字と小文字を区別しない検索

https://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_collat​​ion_server

このすべてが私をこのミームを作成するように導きました:

enter image description here

よろしくお願いいたします。

疲れ果てた仲間の開発者。

ありがとう。

15
Jared Menard

同様の問題に遭遇し、ようやく解決しました。最初、私のMySQLconfは次のとおりです。

character-set-server = utf8
collation-server     = utf8_general_ci

ある日、utf8mb4でしか絵文字を正しく保存できないことがわかったので、指定した列の文字セットと照合順序を次のように変更します。

  `nickname` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,

今では、すべてがまだ正常であり、データはJava Webアプリケーションによって保存および正しく表示される可能性があります。

しかし、私が次のようなデータをクエリすると

SELECT * FROM table_name WHERE nickname LIKE '%????%';

エラーが発生します。

最後に、mysqlconfをに変更しました

character-set-server = utf8mb4
collation-server     = utf8mb4_unicode_ci

そして、すべてがうまくいきます。

これはmysqlクライアントのスクリーンショットです。ニックネーム属性に注意してください

11
toien

列の照合順序をutf8mb4_unicode_ciに変更することで、phpMyAdminからこの問題を解決しました。

1
osama ibrahem

データベースを他のサーバーに複製するときにも同じ問題が発生します。照合順序をutf8mb4_general_ciに変更しましたが、正常に機能しているようです。

0
Amit Sharma