天天看點

Mysql中utf8和utf8mb4差別

一、介紹

MySQL在5.5.3之後增加了這個utf8mb4的編碼,mb4就是most

bytes

4的意思,專門用來相容四位元組的unicode。好在utf8mb4是utf8的超集,除了将編碼改為utf8mb4外不需要做其他轉換。當然,為了節省

空間,一般情況下使用utf8也就夠了。

二、内容描述

那上面說了既然utf8能夠存下大部分中文漢字,那為什麼還要使用utf8mb4呢? 原來mysql支援的 utf8 編碼最大字元長度為 3

位元組,如果遇到 4 位元組的寬字元就會插入異常了。三個位元組的 UTF-8 最大能編碼的 Unicode 字元是 0xffff,也就是

Unicode 中的基本多文種平面(BMP)。也就是說,任何不在基本多文本平面的 Unicode字元,都無法使用 Mysql 的 utf8

字元集存儲。包括 Emoji 表情(Emoji 是一種特殊的 Unicode 編碼,常見于 ios 和 android

手機上),和很多不常用的漢字,以及任何新增的 Unicode 字元等等。

三、問題根源

最初的 UTF-8 格式使用一至六個位元組,最大能編碼 31 位字元。最新的 UTF-8 規範隻使用一到四個位元組,最大能編碼21位,正好能夠表示所有的 17個 Unicode 平面。

utf8 是 Mysql 中的一種字元集,隻支援最長三個位元組的 UTF-8字元,也就是 Unicode 中的基本多文本平面。

Mysql 中的 utf8 為什麼隻支援持最長三個位元組的 UTF-8字元呢?我想了一下,可能是因為 Mysql 剛開始開發那會,Unicode

還沒有輔助平面這一說呢。那時候,Unicode 委員會還做着 “65535 個字元足夠全世界用了”的美夢。Mysql

中的字元串長度算的是字元數而非位元組數,對于 CHAR 資料類型來說,需要為字元串保留足夠的長。當使用 utf8 字元集時,需要保留的長度就是

utf8 最長字元長度乘以字元串長度,是以這裡理所當然的限制了 utf8 最大長度為 3,比如 CHAR(100) Mysql 會保留

300位元組長度。至于後續的版本為什麼不對 4 位元組長度的 UTF-8

字元提供支援,我想一個是為了向後相容性的考慮,還有就是基本多文種平面之外的字元确實很少用到。

要在 Mysql 中儲存 4 位元組長度的 UTF-8 字元,需要使用 utf8mb4 字元集,但隻有 5.5.3 版本以後的才支援(檢視版本:

select version();)。我覺得,為了擷取更好的相容性,應該總是使用 utf8mb4 而非 utf8. 對于 CHAR

類型資料,utf8mb4 會多消耗一些空間,根據 Mysql 官方建議,使用 VARCHAR 替代 CHAR