1. 程式人生 > >utf8和utf8mb4的區別

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 字元等等(utf8的缺點)。

   三、問題根源

   最初的 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。

   引用批註

   [1] 談談字符集與字元編碼

   [2] 關於 MySQL UTF8 編碼下生僻字元插入失敗/假死問題的分析

簡單來說資料庫若設定為utf8則無法插入4位元組的寬字元,還有一些小表情無法儲存