萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL VARCHAR 長度限制深度解析:版本差異、編碼影響與行大小計算

版本演進

MySQL 版本VARCHAR 最大長度備註
5.0.3 之前255超過需用 TEXT/BLOB
5.0.3 及以上65,535實際可存 65,532 位元組(扣除長度前綴)

三大限制規則

1. 儲存限制:長度前綴開銷

  • 實際內容存放在聚簇索引外部
  • 長度 < 255:1 位元組前綴
  • 長度 ≥ 255:2 位元組前綴
  • 因此理論上限 = 65,535 - 1 或 2 = 65,533/65,532 位元組

2. 編碼長度限制:字符集決定單字符位元組數

字符集單字符最大位元組VARCHAR 最大字符數 (65,532 / 單字符位元組)
latin1165,532
gbk232,766
utf8321,844
utf8mb4416,383

超過此限制會自動轉為 TEXT 型別並產生 Warning。

3. 行大小限制:單行所有欄位總和 ≤ 65,535 位元組

錯誤訊息:ERROR 1118 (42000): Row size too large...

實際計算範例

範例 A:單一 VARCHAR(gbk)

CREATE TABLE t4 (c VARCHAR(N)) CHARSET=gbk;
-- N_max = (65535 - 1 - 2) / 2 = 32,766
-- 扣除:行起始1位元組 + 長度前綴2位元組,除以gbk雙字節

範例 B:混合欄位表 (utf8)

CREATE TABLE t4 (
    c1 INT,
    c2 CHAR(30),
    c3 VARCHAR(N)
) CHARSET=utf8;

-- 固定開銷計算:
-- 行起始: 1
-- VARCHAR長度前綴: 2
-- c1 INT: 4 位元組
-- c2 CHAR(30): 30 × 3 = 90 位元組 (utf8固定長)
-- 可用餘額: 65535 - 1 - 2 - 4 - 90 = 65,438 位元組
-- N_max = 65,438 / 3 = 21,812 字符

範例 C:被強制轉為 TEXT 後

  • 每個 TEXT/BLOB 欄位在行中僅佔 11 位元組(指標)
  • 實際資料存放在溢位頁面
  • 此時不再受單行 65KB 限制,但失去 VARCHAR 的就地存取優勢

最佳實踐建議

  1. 預估最大字符數:按業務最長值 + 20% 冗餘設計
  2. 優先使用 utf8mb4:支援 Emoji,最大長度 16,383 字符通常足夠
  3. 避免過大 VARCHAR:超過 1KB 建議改用 TEXT/JSON,減少行溢位概率
  4. 固定長用 CHAR:如 MD5(32)、UUID(36)、手機號(11) 用 CHAR 更高效
  5. 監控行大小:SELECT MAX(LENGTH(col)) FROM tbl; 定期檢查實際佔用

常見誤區

❌ 誤區:VARCHAR(65535) 就能存 65535 個中文

✅ 事實:UTF-8 下最多 21,844 字符;且受單行總長限制,其他欄位會佔用額度。

❌ 誤區:VARCHAR 不佔用行儲存空間

✅ 事實:短資料(< 40 位元組)可能內聯在聚簇索引頁面;長資料溢位到外部頁面,行中保留 20 位元組指標。

copyright © 萬盛學電腦網 all rights reserved