官方文檔:MySQL 8.0 Reference Manual: 10.9.2 The utf8mb3 Character Set (3-Byte UTF-8 Unicode Encoding)
首先,上結論:
- 國際上的
UTF-8
,在MySQL中,對標的是uft8mb4
。 - 在MySQL中,實際只有
utf8mb4
和utf8mb3
。至於uft8
,在 V8.0 還是指代的utf8mb3
,未來的會變爲uft8mb4
。
譯者注:mb3
maximun of 3 bytes per multibyte character.
國際上的UTF-8簡介 作者“蒼楓露雨”[Java Unicode編碼 及 Mysql utf8 utf8mb3 utf8mb4 的區別與utf8mb4的過濾]
UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字符編碼,也是一種前綴碼。它可以用>來表示Unicode標準中的任何字符,且其編碼中的第一個字節仍與ASCII兼容,這使得原來處理ASCII字符的軟件無須或>只須做少部分修改,即可繼續使用。因此,它逐漸成爲電子郵件、網頁及其他存儲或發送文字的應用中,優先採用的編>碼。
UTF-8使用一至四個字節爲每個字符編碼(2003年11月UTF-8被RFC 3629重新規範,只能使用原來Unicode定義的區域,U+0000到U+10FFFF,也就是說最多四個字節):
- 128個US-ASCII字符只需一個字節編碼(Unicode範圍由U+0000至U+007F)。
- 帶有附加符號的拉丁文、希臘文、西裏爾字母、亞美尼亞語、希伯來文、阿拉伯文、敘利亞文及它拿字母則需要兩個字節編碼(Unicode範圍由U+0080至U+07FF)。
- 其他基本多文種平面(BMP, Basic Multilingual Plane)中的字符(這包含了大部分常用字,例如CJVK常用字字符集 —— Chinese, Japanese, Vietnam, Korean)使用三個字節編碼(Unicode範圍由U+0800至U+FFFF)。
- 其他使用極少的Unicode 輔助平面(Supplementary Multilingual Plane)的字符使用四字節編碼(Unicode範圍由U+10000至U+10FFFF,主要包括不常用的CJK字符, 數學符號, emoji表情等)。
具體來講是這樣的:
uft8mb3
:
- 支持&僅且支持BMP characters(不支持supplementary characters)
- 每個multibyte-character,都不多於3個bytes
uft8mb4
:
- 要想支持BMP characters + supplementary characters,既國際上的
(4bytes) UTF-8
,用uft8mb4
(見官方文檔 Section 10.9.1, “The utf8mb4 Character Set (4-Byte UTF-8 Unicode Encoding)”)
(MySQL的)utf8
是utf8mb3
的別名:
- MySQL裏,
utf8
的是隱式的,等價於utf8mb3
,但是但從名稱上是看不出最大字符數的。
好消息是MySQL在未來會改正uft8的命名:“在未來的MySQL版本中會刪除
utf8mb3
,請改用utf8mb4
。雖然utf8
目前是utf8mb3
的別名,但在未來某個時候,utf8
將指代utf8mb4
。爲了避免對utf8
的含義產生歧義,可以考慮直接把字符集引用指定爲utf8mb4
,而不是utf8
。”
附註:
Adam Hooper 在****《In MySQL, never use “utf8”. Use “utf8mb4”.》吐槽:“
- “MySQL在命名上是渣渣。
- MySQL的‘
uft8mb4’
裏每個character佔用4 bytes,這個標準是everybody、>everybody、everybody在everywhere、everywhere、everywhere都用的,MySQL>>應該把它叫做‘utf8
’。- MySQL的‘
uft8mb3’
裏每個character佔用3 bytes,nobody、nobody、nobody在>anywhere、anywhere、anywhere用:它應該被叫做‘utf8mb3
’。
或許,在整個互聯網界,MySQL的‘utf8
’定義都沒人shai。”
- 一點關於MySQL的歷史“ :
-
爲什麼MySQL開發者把utf8鬼改了?從提交的日誌裏,我們能推測出來。
-
MySQL從Version 4.1開始支持
utf8
。彼時,現行utf8
標準RFC 3629沒發佈,老版本RFC 2279最多還支持6 bytes/Charactor呢。2002年3月28日,在the first pre-pre-relase version of MySQL4.1裏,MySQL開發人員碼入了RFC 2279。 -
在2002年9月MySQL的源代碼上,出現了一個神祕的篡改,“自此
utf8
的一個character最多支持3 byte sequences only 。”即每個character短了1 byte。
-
-
誰改的?爲什麼?無從得知。在MySQL改用Git那會,日誌好像丟了原作者的名,(MySQL之前和Linux一樣,kernel用的BitKeeper),在2003年9月前後的mailing list裏,現在找不到一個更改源代碼的註釋。
但我能猜啊!-
時間回到2002年,那會用戶能體驗MySQL的speed boost功能,如果保證table裏每一行的bytes一樣,即text column是’
CHAR
'類型(‘CHAR
’格式下,字段的長度bytes一樣)。
在這之後的某個時間,MySQL開發人員開始嘗試utf8
,請注意那會它還是 6 bytes/character,他應該猶豫了:一個 CHAR(1) 會佔用6 bytes;那麼一個CAHR(2)就佔12 bytes,依次類推。 -
我們要知道:那個剛開始的,即沒有被髮布的MySQL版本,是沒鬼改的utf8。它的官方文檔甚至都寫好了,是個知道
utf8
的人認可。
但是明顯的,某個MySQL開發員工(合作某個businessperson)十分關注一兩個要這麼做的客戶:- 選出
CHAR
列(CHAR
格式在今天看是個古董,但在當時,MySQL靠它能運行地更快。自打2005年後,它就不怎麼地了) - 用
utf8
編碼這些CHAR
列。
- 選出
-
我推測,這個MySQL開發員工改了初版
utf8
的MySQL,想這樣幫助用戶:兼顧空間和速度。 -
結果是誰賠了夫人又折兵。一方面,想要speed和space的用戶失算了,因爲
utf8
的CHAR
類型的字段,該大的還是大,該慢的還是慢。另一方面,當初要給MySQL添加utf8
的開發員也是瞎折騰了一趟,因爲鬼改版utf8
MySQL “?”(emoji表情)都存不了。 -
自打鬼改版的
utfmb3
MySQL發佈那一刻,就再也改不了了:總不能強迫每一個用戶從頭再搭一遍數據庫吧!好不容易在2010年MySQL支持了完整版的utf8
,卻搞了一個奇葩的名字utf8mb4
。”
-