MySQL 單行記錄最大長度硬性限制為 65,535 字節。但實際可用空間受字符集編碼、VARCHAR 長度前綴、NULL 位圖等因素顯著壓縮。本文量化分析各因素開銷,指導表結構設計避坑。
所有列定義長度之和 ≤ 65,535 bytes
超過報錯:Row size too large (> 8126). Changing some columns to TEXT or BLOB may help.
| 字符集 | 英文/數字 | 漢字/全角 | 備註 |
|---|---|---|---|
| latin1 | 1 byte | 不支持 | 單字節編碼 |
| gbk | 1 byte | 2 bytes | 雙字節編碼 |
| utf8 (utf8mb3) | 1 byte | 3 bytes | BMP 字符 |
| utf8mb4 | 1 byte | 4 bytes | 含 Emoji/生僻字 |
VARCHAR(100) CHARSET utf8mb4 最大佔用 100 × 4 = 400 bytes + 長度前綴。
CEILING(列數 / 8) 字節的 NULL 位圖。NOT NULL 可完全省去此開銷。表結構:
CREATE TABLE demo ( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) CHARSET utf8mb4, -- 允許 NULL content VARCHAR(500) CHARSET utf8mb4, -- 允許 NULL status TINYINT NOT NULL DEFAULT 0 ) ENGINE=InnoDB;
id (INT) = 4 bytesname = 100 × 4 (utf8mb4) + 2 (前綴) = 402 bytescontent = 500 × 4 + 2 = 2002 bytesstatus (TINYINT) = 1 byteCEILING(2/8) = 1 byte若改為 VARCHAR(16000) utf8mb4 兩列:
單列 = 16000 × 4 + 2 = 64002 bytes → 兩列即超標。
解決:拆分大文本為 TEXT/MEDIUMTEXT/LONGTEXT(溢出頁存儲,僅在行內存 20 字節指針)。
TEXT 族類型。SHOW TABLE STATUS 查看 Avg_row_length 監控實際行長度。掌握行長度核算邏輯,可在建表階段規避「Row size too large」報錯,設計出緊湊高效的表結構。