首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL "Row size too large 65535" 錯誤原因分析與修正策略 (補充說明版)

     編輯:MySQL 綜合教學

MySQL 行大小超限 65535 位元組錯誤的補充技術細節與避坑指南

本文為前文 (ID 171750) 的補充,針對錯誤觸發條件、VARCHAR 版本差異、TINYTEXT 適用邊界、InnoDB 行格式影響進行更深入說明,幫助開發者精準判斷何時需變更欄位類型。

錯誤觸發的精確條件

  • 執行 CREATE TABLE、ALTER TABLE ... ADD COLUMN、ALTER TABLE ... MODIFY COLUMN 時,MySQL 會計算**所有非 BLOB/TEXT 欄位的最大可能儲存長度總和** (含長度前綴 1-2 bytes)。
  • 若總和 > 65535,直接報錯 Row size too large,**即使實際資料極短也會被攔截**,因為是靜態定義檢查。
  • TEXT/BLOB 欄位行內固定佔 20 bytes (指標),**不計入 65535 計算**,故改為 TEXT 類型可繞過檢查。

VARCHAR 儲存開銷版本差異 (關鍵)

若表建立於舊版再升級,VARCHAR(300) 實際行內開銷為 2 bytes 長度 + 300×字元位元組,較新版定義更佔預算。

TINYTEXT 適用邊界與取捨

  • 優點:行內固定 1 byte 長度 + 20 bytes 指標 = 21 bytes,極省行預算;最大 255 字元,符合多數代碼/標籤/短描述欄位。
  • 缺點:不支援 DEFAULT 值 (5.7 前);無法建立索引前綴長度 > 255;排序/分組需臨時表較慢。
  • 決策表:
版本長度前綴最大字元數備註
5.0.3 前1 byte255 字元長度 0-255
5.0.3+1-2 bytes65535 字元長度 0-65535;>255 字元時前綴 2 bytes
業務最大長度建議類型理由
≤ 255 字元、高頻讀寫VARCHAR(N)支援 DEFAULT、索引、就地更新
≤ 255 字元、低頻、需省行預算TINYTEXT行內最小開銷
256 - 65535 字元TEXT自動溢頁,行內固定 20 bytes
> 64KBLONGTEXT / 拆表超出 TEXT 上限

InnoDB 行格式對行大小限制的影響

  • ROW_FORMAT=COMPACT/REDUNDANT (5.7 預設 COMPACT):**受 65535 限制**,大欄位若超過頁面 1/2 會溢頁,但定義長度仍計入行預算。
  • ROW_FORMAT=DYNAMIC/COMPRESSED (需 innodb_file_per_table=ON + innodb_large_prefix=ON,5.7.7+ 預設開啟):大幅放寬,支援單行超過 64KB (實際上限約 16MB),**大欄位完全溢頁不計入行內預算**。
  • 檢查表格式:SHOW TABLE STATUS LIKE 'tbl'\G 看 Row_format。
  • 若已是 DYNAMIC 仍報錯,檢查是否有大量 VARCHAR 但未超過溢頁門檻 (40 bytes),可強制改為 TEXT 觸發溢頁。

快速診斷腳本 (生產庫可直接跑)

SELECT 
  TABLE_NAME,
  SUM(
    CASE DATA_TYPE
      WHEN 'varchar' THEN CHARACTER_MAXIMUM_LENGTH * 
        CASE CHARACTER_SET_NAME WHEN 'utf8mb4' THEN 4 WHEN 'utf8' THEN 3 ELSE 1 END + 2
      WHEN 'char' THEN CHARACTER_MAXIMUM_LENGTH * 
        CASE CHARACTER_SET_NAME WHEN 'utf8mb4' THEN 4 WHEN 'utf8' THEN 3 ELSE 1 END
      WHEN 'varbinary' THEN CHARACTER_MAXIMUM_LENGTH + 2
      WHEN 'binary' THEN CHARACTER_MAXIMUM_LENGTH
      ELSE 0 END
  ) AS est_row_bytes
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'your_db'
  AND DATA_TYPE NOT IN ('text','blob','longtext','mediumtext','tinytext')
GROUP BY TABLE_NAME
HAVING est_row_bytes > 60000
ORDER BY est_row_bytes DESC;

結果中 est_row_bytes 越接近 65535 越危險,優先處理。

總結

  1. 錯誤本質:**靜態定義長度總和 > 64KB**,與實際資料量無關。
  2. 核心對策:**將低頻、短長度 VARCHAR 遷移為 TINYTEXT/TEXT**,釋放行預算。
  3. 長期規劃:**新表採用 DYNAMIC 行格式 + utf8mb4 + 拆分大欄位**,從架構層面避開限制。

理解儲存引擎行格式與欄位類型的交互關係,才能在 schema 設計階段就規避此類硬性限制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved