萬盛學電腦網

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

MySQL 错误 #1062 Duplicate entry 根因:自增列类型溢出(TINYINT/SMALLINT/INT 范围详解)

MySQL 错误 #1062 Duplicate entry 根因:自增列类型溢出(TINYINT/SMALLINT/INT 范围详解)

開發測試階段報錯 Duplicate entry '127' for key 1 或 '32767',乍看像主鍵衝突,實則是 自增列數據類型範圍耗盡。本文詳細列出 MySQL 整數類型範圍、溢出癥狀、定位方法與修復方案。

一、錯誤現場還原

Invalid Query: Duplicate entry '127' for key 1
SQL: INSERT INTO kq_news (Title,Author,Type,Content,IsDel,Adate,Range,Lang) 
     VALUES ('捐款活動','yuanying','3','','0',NOW(),'2','cn')

表結構中 id TINYINT AUTO_INCREMENT PRIMARY KEY,插入第 128 條時嘗試生成 128,超出 TINYINT UNSIGNED 上限 255?實際報 127 說明是 有符號 TINYINT(上限 127)。

二、MySQL 整數類型完整範圍表

類型存儲字節有符號範圍無符號範圍適用場景
TINYINT1-128 ~ 1270 ~ 255極小枚舉、狀態碼、布爾替代
SMALLINT2-32,768 ~ 32,7670 ~ 65,535小型字典表、配置項 ID
MEDIUMINT3-8,388,608 ~ 8,388,6070 ~ 16,777,215中型業務表主鍵(百萬級)
INT / INTEGER4-2,147,483,648 ~ 2,147,483,6470 ~ 4,294,967,295通用主鍵標準選擇(21 億)
BIGINT8-9.22e18 ~ 9.22e180 ~ 1.84e19超大規模、分布式 ID、雪花算法

三、溢出癥狀對照表

報錯 Duplicate entry 值對應類型有/無符號已插入行數
127TINYINTSIGNED127
255TINYINTUNSIGNED255
32,767SMALLINTSIGNED32,767
65,535SMALLINTUNSIGNED65,535
2,147,483,647INTSIGNED21.4 億

四、定位與修復步驟

  1. 確認表結構:SHOW CREATE TABLE tbl_name\G 查看 id 定義。
  2. 檢查當前最大值:SELECT MAX(id) FROM tbl_name;
  3. 修改列類型(需停機或在線 DDL):
    -- 方案 A:直接擴大類型(MySQL 5.6+ Online DDL)
    ALTER TABLE tbl_name MODIFY COLUMN id INT UNSIGNED AUTO_INCREMENT;
    
    -- 方案 B:大表零停機(pt-online-schema-change)
    pt-online-schema-change --alter "MODIFY COLUMN id BIGINT UNSIGNED AUTO_INCREMENT" D=db,t=tbl_name --execute
  4. 重置自增值(可選):ALTER TABLE tbl_name AUTO_INCREMENT = 1000;
  5. 驗證插入:插入測試行確認無報錯。

五、預防最佳實踐

  1. 新表默認用 BIGINT UNSIGNED 或 INT UNSIGNED:除非極確定行數永不超百萬,否則別用 SMALLINT/TINYINT 做主鍵。
  2. 監控自增值消耗率:SELECT MAX(id)/4294967295 * 100 AS pct FROM tbl; 納入巡檢。
  3. 分庫分表預留空間:雪花算法 ID 用 BIGINT,單表自增預留 10 倍增長空間。
  4. 開發規範:Code Review 必查主鍵類型,禁止「先用 TINYINT 測試,上線再改」。

六、補充:AUTO_INCREMENT 重用陷阱

DELETE 刪除最大 ID 行後,MyISAM 會重用該 ID,InnoDB 不重用(內存計數器單調遞增)。重啟後 InnoDB 重新計算 MAX(id)+1,可能導致自增值「倒退」但不衝突。若業務強依賴 ID 單調遞增不可復用,請用 BIGINT + 雪花算法生成。

copyright © 萬盛學電腦網 all rights reserved