實際場景問題之Emoji表情如何操作存儲,MySQL是否支持
針對 Emoji 表情 MySQL 存儲是否支持的問題,結論是:
MySQL 中可以存儲 emoji 表情,但需要使用 UTF8MB4 字符編碼。如果使用 UTF8MB3,存儲這些擴展字符會導致解析錯誤。
課外補充
MySQL 對 Unicode 的支持
Unicode 字符集已成為計算機科學領域的業界標準,它整理、編碼了世界上大部分的文字系統,使得計算機能夠更簡便地呈現和處理文字。
為了滿足不同的數據存儲和傳遞需求,人們開發了多種 Unicode Transformation Format(UTF)編碼。主要的 UTF 編碼包括 UTF-8、UTF-16 和 UTF-32 等。
根據 MySQL 官方文檔
MySQL 主要支持以下字符集:utf8、ucs2、utf8mb3、utf8mb4、utf16、utf16le 和 utf32。這些字符集在支持的字符范圍和存儲空間需求上有所不同。
字符集 | 支持的字符 | 每個字符所需存儲空間 |
utf8mb3, utf8 | BMP | 1-3 字節 |
ucs2 | BMP | 2 字節 |
utf8mb4 | BMP 和補充字符 | 1-4 字節 |
utf16 | BMP 和補充字符 | 2 或 4 字節 |
utf16le | BMP 和補充字符 | 2 或 4 字節 |
utf32 | BMP 和補充字符 | 4 字節 |
在 MySQL 官方文檔中,介紹了支持的編碼方式之后,還有一段醒目的提醒:
圖片
以上文字大致意思是:"UTF8MB3 字符集已被棄用,它在未來的 MySQL 版本中將會被刪除,請使用 UTF8MB4 代替。在目前的 8.0 版本中,utf8 指的就是 UTF8MB3,雖然未來可能改成 UTF8MB4,但是為了避免產生歧義,可以考慮為字符集引用顯式指定 UTF8MB4,而不是 utf8。"
這段話的意思是,MySQL 8.0 版本中使用 UTF-8 字符編碼實際上是使用了 utf8mb3 編碼方式,但 UTF8MB3 已經被棄用,并且在未來的 MySQL 版本中會被移除。因此,建議在設定字符集時明確指定 UTF8MB4,以避免將來可能引起的歧義和問題。
現在我們來詳細討論 UTF8MB3 的情況。
UTF8MB3
utf8mb3 字符集是 MySQL 早期支持的一種字符集,具有以下特征:
- 僅支持 Basic Multilingual Plane(BMP)中的字符,不支持補充字符。
- 每個多字節字符最多需要三個字節來表示。
BMP 指的是基本多文種平面,其中的字符碼位范圍在 0 到 65535(或者用 Unicode 表示為 U+0000 到 U+FFFF)。這意味著 utf8mb3 無法存儲碼位在 U+10000 到 U+10FFFF 之間的補充字符,包括一些生僻的漢字和 Emoji 表情等。
因此,如果在創建 MySQL 表時使用 utf8mb3(即 utf-8)作為字符編碼方式,就無法正確存儲和處理補充字符。
UTF8MB4
早期的 Unicode 版本只使用了 0 到 0xFFFF 范圍的編碼,稱為 BMP(Basic Multilingual Plane)字符集。因此,最初 MySQL 設計時只涵蓋了支持 BMP 字符集的 utf8mb3(即 utf-8)。隨著需求增加,包含在 Unicode 標準中的字符數量也增加了。
因此,早期的 utf8mb3 在某些情況下無法滿足需求,特別是隨著 Unicode 標準支持更多字符時,三個字節的編碼空間變得不足以覆蓋所有字符。
為了解決這個問題,MySQL 在 5.5.3 版本之后引入了 utf8mb4 字符集。
utf8mb4 字符集具有以下特點:
- 支持 BMP 和補充字符,即能夠表示從 0 到 0x10FFFF 的所有 Unicode 字符。
- 每個多字節字符最多需要四個字節來編碼。
utf8mb4 與 utf8mb3 字符集不同的地方在于,utf8mb3 僅能表示 BMP 字符,而 utf8mb4 則能夠處理補充字符。對于 BMP 字符,utf8mb4 和 utf8mb3 的存儲方式相同,但對于補充字符,utf8mb4 需要四個字節來存儲,而 utf8mb3 則無法處理這些字符。
因此,為了確保能夠存儲和處理 Unicode 標準中的所有字符,特別是包括 Emoji 表情在內的補充字符,建議在創建 MySQL 表時使用 utf8mb4 字符集,而不是 utf8。
UTF8MB3 和 UTF8MB4 區別及優缺點
前面已經分別介紹了 utf8mb3 和 utf8mb4 字符集,它們的區別總結如下:
- utf8mb3 只支持 BMP(Basic Multilingual Plane)中的字符,而 utf8mb4 則支持 BMP 以及補充字符。
- 每個字符在 utf8mb3 中最多使用 3 個字節來編碼,而在 utf8mb4 中最多使用 4 個字節。
- utf8mb4 能夠表示更多的補充字符,但因為每個字符可能使用更多的字節,所以在存儲空間上可能會比 utf8mb3 占用更大。
總之,utf8mb4 相比 utf8mb3 提供了更廣泛的字符支持,尤其是對于包含 Emoji 表情在內的補充字符,但這也可能導致數據存儲時占用更多的空間。
從 utf8mb3 轉換成 utf8mb4
首先,將字符集從 utf8mb3 轉換到 utf8mb4 其實并不困難:
對于 BMP 字符,utf8mb4 和 utf8mb3 具有相同的存儲特性:相同的編碼值、相同的編碼方式以及相同的長度。
對于補充字符,utf8mb4 需要使用 4 個字節進行存儲,而 utf8mb3 則無法存儲這些字符。當將使用 utf8mb3 的列轉換為 utf8mb4 時,您無需擔心補充字符的轉換問題,因為 utf8mb3 根本不支持補充字符。
假設已有一張表使用了 utf8mb3 字符集:
CREATE TABLE t1 (
col1 CHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
col2 CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
) CHARACTER SET utf8;
下面的語句將 t1 轉換為 utf8mb4:
ALTER TABLE t1
DEFAULT CHARACTER SET utf8mb4,
MODIFY col1 CHAR(10)
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
MODIFY col2 CHAR(10)
CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL;