擁有字元集“utf8mb4” - 這是否意味著每個字元都需要 4 個字節,還是只需要那些需要 4 個字節的字元?
我有一個
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 引擎具有所謂的“溢出頁面”,用於所有長數據所在的表儲存。根頁面僅儲存索引的前綴和指向下一頁的指針。
TEXT
和BLOB
類型也是如此。這就是為什麼返回的表的“行大小”
SHOW TABLE STATUS
可以小於表能夠儲存的最大數據大小。