首頁  >  文章  >  資料庫  >  MySQL表排序規則不同報錯問題分析

MySQL表排序規則不同報錯問題分析

小云云
小云云原創
2017-12-14 11:49:311681瀏覽

MySQL多表join時報錯如下:[Err]1267 – Illegal mix of collat​​ions(utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation '=

#就是說兩個表的排序規則(COLLATION)不同,無法完成比較。 COLLATION是用在排序,大小比較上,一個字元集有一個或多種COLLATION,並且以_ci(大小寫不敏感)、_cs(大小寫敏感)或_bin(二進位)結束。在做比較時,應該確保兩個表的字元排序相同。一般建表的時候不指定,可以走預設的,全是預設的就沒什麼問題了。本文主要介紹了MySQL表排序規則不同錯誤問題分析,希望能幫助大家。

下面來模擬各種場景,表格結構如下(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表連接

php mysql表中文亂碼問題如何解決

#

以上是MySQL表排序規則不同報錯問題分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn