欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MySQL表排序规则不同错误问题分析

程序员文章站 2022-05-14 20:50:39
mysql多表join时报错如下:[err]1267 – illegal mix of collations(utf8_general_ci,implicit) and (...

mysql多表join时报错如下:[err]1267 – illegal mix of collations(utf8_general_ci,implicit) and (utf8_unicode_ci,implicit) for operation ‘=

就是说两个表的排序规则(collation)不同,无法完成比较。collation是用在排序,大小比较上,一个字符集有一个或多种collation,并且以_ci(大小写不敏感)、_cs(大小写敏感)或_bin(二进制)结束。在做比较时,应该确保两个表的字符排序相同。一般建表的时候不指定,可以走默认的,全是默认的就没什么问题了。

下面来模拟一下各种场景,表结构如下(utf8默认排序规则为utf8_general_ci):

mysql> show create table test.cs\g
*************************** 1. row ***************************
    table: cs
create table: create table `cs` (
 `id` int(11) default null,
 `name` varchar(10) default null
) engine=innodb default charset=utf8
1 row in set (0.01 sec)

查看表默认排序规则集

mysql> select table_schema,table_name,table_collation from information_schema.tables where table_name='cs';
+--------------+------------+-----------------+
| table_schema | table_name | table_collation |
+--------------+------------+-----------------+
| test     | cs     | utf8_general_ci |
+--------------+------------+-----------------+
1 row in set (0.00 sec)

查看列排序规则集

mysql> select table_schema,table_name,column_name,collation_name from information_schema.columns where table_name='cs';
+--------------+------------+-------------+-----------------+
| table_schema | table_name | column_name | collation_name |
+--------------+------------+-------------+-----------------+
| test     | cs     | id     | null      |
| test     | cs     | name    | utf8_general_ci |
+--------------+------------+-------------+-----------------+
2 rows in set (0.00 sec)

从utf8升级为utf8mb4是不支持online ddl的,如下:

mysql> alter table cs convert to character set utf8mb4,algorithm=inplace,lock=none;
error 1846 (0a000): algorithm=inplace is not supported. reason: cannot change column type inplace. try algorithm=copy.

从utf8.utf8_general_ci变更为utf8.utf8_unicode_ci是不支持online ddl的,如下:

mysql> alter table cs convert to character set utf8 collate utf8_unicode_ci,algorithm=inplace,lock=none;
error 1846 (0a000): algorithm=inplace is not supported. reason: cannot change column type inplace. try algorithm=copy.

如果使用下面这种方式修改字符集,你会发现,只更改了表级的,没有更改列级的。

mysql> alter table cs character set utf8 collate utf8_unicode_ci;      
query ok, 0 rows affected (0.01 sec)
records: 0 duplicates: 0 warnings: 0
 
mysql> select table_schema,table_name,table_collation from information_schema.tables where table_name='cs';      
+--------------+------------+-----------------+
| table_schema | table_name | table_collation |
+--------------+------------+-----------------+
| test     | cs     | utf8_unicode_ci |
+--------------+------------+-----------------+
1 row in set (0.00 sec)
 
mysql> select table_schema,table_name,column_name,collation_name from information_schema.columns where table_name='cs';
+--------------+------------+-------------+-----------------+
| table_schema | table_name | column_name | collation_name |
+--------------+------------+-------------+-----------------+
| test     | cs     | id     | null      |
| test     | cs     | name    | utf8_general_ci |
+--------------+------------+-------------+-----------------+
2 rows in set (0.00 sec)

所以真正改字符集的时候别忘了加上convert to,如下:

mysql> alter table cs convert to character set utf8 collate utf8_unicode_ci;
query ok, 5 rows affected (0.06 sec)
records: 5 duplicates: 0 warnings: 0
 
mysql> select table_schema,table_name,column_name,collation_name from information_schema.columns where table_name='cs';
+--------------+------------+-------------+-----------------+
| table_schema | table_name | column_name | collation_name |
+--------------+------------+-------------+-----------------+
| test     | cs     | id     | null      |
| test     | cs     | name    | utf8_unicode_ci |
+--------------+------------+-------------+-----------------+
2 rows in set (0.00 sec)

要仅仅改变一个表的默认字符集,应使用此语句:

mysql> alter table cs default character set utf8 collate utf8_general_ci,algorithm=inplace,lock=none;         
query ok, 0 rows affected (0.00 sec)
records: 0 duplicates: 0 warnings: 0
 
mysql> select table_schema,table_name,table_collation from information_schema.tables where table_name='cs';      
+--------------+------------+-----------------+
| table_schema | table_name | table_collation |
+--------------+------------+-----------------+
| test     | cs     | utf8_general_ci |
+--------------+------------+-----------------+
1 row in set (0.00 sec)
 
mysql> select table_schema,table_name,column_name,collation_name from information_schema.columns where table_name='cs';  
+--------------+------------+-------------+-----------------+
| table_schema | table_name | column_name | collation_name |
+--------------+------------+-------------+-----------------+
| test     | cs     | id     | null      |
| test     | cs     | name    | utf8_unicode_ci |
+--------------+------------+-------------+-----------------+
2 rows in set (0.00 sec)

可以发现列字符集没有改变,并且只有新的列才会默认继承表的字符集(utf8.utf8_general_ci)。

总结

以上就是本文关于mysql表排序规则不同错误问题分析的全部内容,希望对大家有所帮助。感兴趣的朋友可以参阅:几个比较重要的mysql变量mysql 声明变量及存储过程分析mysql主库binlog(master-log)与从库relay-log关系代码详解mysql prepare原理详解等,有什么问题可以随时留言,互相交流,共同进步。