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




















