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;
搞定了。解决问题还是要找到根源。