mysql中utf8和utf8mb4的區別


mysql中 utf8 和 utf8mb4 的區別

今年上半年,優化過一批報表查詢的功能,在過程中遇到了這個問題,因為兩張表字段一個是 utf8 一個是 utf8mb4 ,導致查詢一直無法使用索引,最后把字段全都改為 utf8mb4 就好了,當時我就只是認為這兩種字符集不同,並沒有繼續深究下去。

今天突然在一個公眾號上講到mysql中 utf8 和 utf8mb4 的問題,於是我查了一些資料才弄懂這件事情,然后總結了一些后續使用mysql的注意事項。

問題描述

1、我遇到的情況是這樣:

假設第一張表是student(學生)表,第二張表是class(班級)表。

image-20200902102716433

studentId和classId分別是兩張表的主鍵,現在我要查詢所有學生和他們的班級信息,非常簡單的一個問題,在數據量多的情況下,我突然發現這個簡單的查詢會變的很慢,並且把班級表的關聯去掉就會瞬間出結果,我聽過EXPLAIN關鍵字對sql進行了分析,發現的問題是class這張表關聯的時候並沒有走主鍵的索引,導致查詢會掃描整張class表。

接下來我把所有可能的有可能情況都排除了,還是沒有找到問題,后來無意間發現了兩張表的classId雖然類型都是varchar,但兩者的字符集不同,一個是 utf8 一個是 utf8mb4 ,我把兩張表的類型全都改成 utf8mb4 ,就解決了這個問題。

2、我在一個公眾號上看到案例:

作者在向數據庫插入Emoji 表情的時候數據庫報錯了,也是改成 utf8mb4 之后解決了問題。

那么通過這兩種情況,我們可以知道兩件事情,一是 utf8 和 utf8mb4 不一樣,二是 utf8 不支持Emoji 表情,那為什么會在mysql里面出現這個問題,我們到底該用哪一種字符集?

資料查詢

通過查詢資料,我發現這根本就是一個歷史遺留問題。

utf8mb4 編碼是MySQL在5.5.3之后新增的,mb4就是most bytes 4的意思,是專門拿來兼容四字節unicode,區別就是 utf8mb4 占用四個字節, utf8 占用三個字節。所以第一個問題中雖然兩個類型都是varchar,但是他們的編碼格式其實是不同的。

為什么會出現這種情況,我們要談到unicode編碼了,在最初的時候unicode編碼是16位也就是2個字節,這樣他就可以表示65536個字符,但是大家自己想想,世界上這么多語言,它們的字符數量肯定不止6萬多,所以Unicode4.0定義了一組附加字符編碼,附加字符編碼采用2個16位來表示,也就變成了4個字節。

我們再回到mysql這個問題上, utf8 是mysql中的一種字符集,只支持最長三個字節的UTF-8字符,也就是 Unicode 中的基本多文本平面。這就解釋了為什么Emoji 表情為什么存不進去,因為Emoji 表情是四個字節的。

原因很明了了,是因為在mysql最初的時候unicode都還沒有輔助平面這么一說,后來需要在mysql中保存4個字節長度的字符時,就出現了 utf8mb4 ,為什么沒有直接改變 utf8 呢?有人認為是為了考慮向后兼容性的問題,還有原因是4個字節的字符確實很少用到。

utf8 升級到 utf8mb4 的問題

utf8mb4 是 utf8 的超集,從舊版本的 utf8 升級到 utf8mb4 的時候,不需要擔心字符轉換或者丟失數據。

那么我們如何去升級呢?

SQL 語句

# 修改數據庫:  
ALTER DATABASE database_name CHARACTER SET = utf8mb4  COLLATE = utf8mb4_unicode_ci;  
# 修改表:  
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;  
# 修改表字段:  
ALTER TABLE table_name CHANGE column_name column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;  

修改MySQL配置文件

新增如下參數:

default-character-set =  utf8mb4  
default-character-set =  utf8mb4     
character-set-client-handshake = FALSE  
character-set-server =  utf8mb4   
collation-server =  utf8mb4 _unicode_ci  
init_connect='SET NAMES  utf8mb4 '

檢查環境變量 和測試 SQL 如下:

SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';  

注意:MySQL版本必須為5.5.3以上版本,否則不支持字符集 utf8mb4

建議

個人覺得,雖然 utf8mb4 會多消耗空間,但是為了更好的兼容性,推薦全部使用 utf8mb4,並且使用 varchar 代替 char。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM