OperationalError: (1267, "Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation 'like'")
今天在系統裏做了一箇中文的檢索,結果 就出現如上的錯誤提示,第一反應是數據庫字符集的問題,那麼就按照下面的步驟,一步一步來排查:
1.查看數據庫的字符集是否有問題
mysql> SHOW VARIABLES LIKE 'character_set_%';
+--------------------------+--------------------------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /bin/mysql-5.7.22/share/charsets/ |
+--------------------------+--------------------------------------------------+
仔細看了,上面的字符集確實沒有問題。
2.查看數據庫的排序規則
mysql> SHOW VARIABLES LIKE 'collation_%';
+----------------------+-----------------+
| Variable_name | Value |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database | utf8_bin |
| collation_server | utf8_bin |
+----------------------+-----------------+
同樣是沒有發現問題
3.排查表的字符集
CREATE TABLE `bus` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL DEFAULT '',
`pid` int(11) NOT NULL,
`stat` int(11) NOT NULL,
`dept_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8 |
同樣未見異常,那麼問題就來了,根據報錯信息,一定是字符集的問題導致的,所以通過打開DEBUG開關,觸發報錯,得到報錯對應的sql語句,並將sql語句拿到數據庫的client 端直接運行,得到的結果卻是如標題所示,那麼問題就明朗了,就是這條sql,再具體分析sql的語義後,發現本條sql不僅僅只查了bus 表,還有另一張表,查看結果如下:
CREATE TABLE `data` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`instance_id` int(11) NOT NULL,
`name` varchar(16) NOT NULL,
`business_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `un_idx_instance_id_name` (`instance_id`,`name`),
KEY `indx_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=401 DEFAULT CHARSET=latin1
看到 CHARSET=latin1 了,問題找到,那麼開始改此表的字符集,以及對歷史數據(有中文)的修改
alter table `data` charset=utf8;
alter table `data` convert to character set utf8;
搞定了。解決問題還是要找到根源。