Mysql

擁有字元集“utf8mb4” - 這是否意味著每個字元都需要 4 個字節,還是只需要那些需要 4 個字節的字元?

  • February 18, 2021

我有一個VARCHAR(80) utf8mb4專欄,我正在測試添加一些 ASCII 和表情符號字元,並使用LENGTH()CHAR_LENGTH()了解差異。

從不同的地方閱讀,我的理解是utf8mb4列上的每個字元需要 4 個字節。LENGTH()但是,如果我理解為給我特定內容在該欄位上的實際大小,則情況似乎並非如此。

具有“aaaa”內容的行比具有“😁😁😁😁”的行佔用更少的儲存空間是否正確?

在此處輸入圖像描述

實際上,我的答案在文件中: https ://mariadb.com/kb/en/unicode/

每個字元使用一到三個字節的 UTF-8 編碼。基本的拉丁字母、數字和標點符號使用一個字節。歐洲和中東字母大多適合 2 個字節。韓文、中文和日文的表意文字使用 3 字節。不儲存補充字元。

utf8mb4 – 與 utf8 相同,但將補充字元儲存在四個字節中。

此外,根據https://mariadb.com/kb/en/data-type-storage-requirements/

字元串數據類型

在下面的描述中,M 是聲明的列長度(以字元或字節為單位),而 len 是值的實際長度(以字節為單位)。

VARCHAR(M) – 如果列是 0 – 255 字節,則 len + 1 字節,如果列可能需要超過 255 字節,則 len + 2 字節

因此,對於VARCHAR(80) utf8mb4,

80x4 > 255,因此帶有“aaaa”的欄位將佔用 6 個字節(len + 2)

當 mysql/mariadb 為 UTF8 數據創建列時,它們被創建得足夠大以適合任何具有給定編碼的字元串。

VARCHAR(80) COLLATE 'utf8_general_ci'列的長度正好是 80x3=240 字節。

VARCHAR(80) COLLATE 'utf8mb4_general_ci'列的長度正好是 80x4=320 字節。

PS

InnoDB 引擎具有所謂的“溢出頁面”,用於所有長數據所在的表儲存。根頁面僅儲存索引的前綴和指向下一頁的指針。TEXTBLOB類型也是如此。

這就是為什麼返回的表的“行大小”SHOW TABLE STATUS可以小於表能夠儲存的最大數據大小。

引用自:https://dba.stackexchange.com/questions/285336