首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 字段原子自增自減 SQL 寫法:IF 條件防止無符號整數溢出

     編輯:MySQL 資料庫相關知識

文章評論數、商品庫存等計數器字段常需原子自增/自減。無符號整數(UNSIGNED)自減至 0 再減會發生**下溢回繞**(變為最大值 65535/4294967295),導致嚴重數據錯誤。本文提供單條 SQL 安全寫法。

問題重現

-- comments SMALLINT UNSIGNED (0~65535)
UPDATE info SET comments = comments - 1 WHERE id = 32;
-- 當 comments=0 時,執行後變為 65535(錯誤)

安全寫法:IF 條件保護

-- 自減 1,最小值鎖定 0
UPDATE info SET comments = IF(comments < 1, 0, comments - 1) WHERE id = 32;

-- 通用:自減 x,最小值 0
UPDATE info SET comments = IF(comments < x, 0, comments - x) WHERE id = 32;

-- 自增無上溢風險(除非達到類型上限),直接加
UPDATE info SET comments = comments + 1 WHERE id = 32;

原理解析

  • IF(condition, true_val, false_val):MySQL 流程控制函數,條件為真返回 true_val,否則 false_val。
  • comments < 1 覆蓋 comments = 0 情況,直接返回 0,避開減法運算。
  • 單條語句**原子執行**,無競態條件,無需應用層 SELECT → 判斷 → UPDATE 兩次往返。

擴展:帶上限的自增

-- 庫存扣減,不超過總庫存 total_stock
UPDATE products SET stock = IF(stock >= buy_num, stock - buy_num, 0) WHERE id = 100;

-- 計數器自增,不超過上限 max_val
UPDATE counters SET cnt = IF(cnt < max_val, cnt + 1, max_val) WHERE id = 1;

效能對比

方案SQL 次數鎖持有時間併發安全適用場景
應用層 SELECT+UPDATE2長(含網路 RTT)需額外鎖/樂觀鎖低併發、邏輯複雜
單條 IF SQL1極短(行鎖)原子安全高併發計數器、庫存扣減
存儲過程1短原子安全極複雜邏輯

類型上限速查

類型無符號上限
TINYINT UNSIGNED255
SMALLINT UNSIGNED65,535
MEDIUMINT UNSIGNED16,777,215
INT UNSIGNED4,294,967,295
BIGINT UNSIGNED18,446,744,073,709,551,615

單條 IF 語句,徹底解決無符號整數自減下溢問題,高併發首選。

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