| 類型 | 存儲 | 有符號範圍 | 無符號範圍 |
|---|---|---|---|
| TINYINT | 1B | -128 ~ 127 | 0 ~ 255 |
| SMALLINT | 2B | -32,768 ~ 32,767 | 0 ~ 65,535 |
| MEDIUMINT | 3B | -8,388,608 ~ 8,388,607 | 0 ~ 16,777,215 |
| INT | 4B | -2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 |
| BIGINT | 8B | -9.22e18 ~ 9.22e18 | 0 ~ 1.84e19 |
SELECT CAST(0 AS UNSIGNED) - 1; -- 無符號下溢 SELECT 9223372036854775807 + 1; -- 有符號上溢 (BIGINT MAX)
mysql> SELECT CAST(0 AS UNSIGNED) - 1; +-------------------------+ | CAST(0 AS UNSIGNED) - 1 | +-------------------------+ | 18446744073709551615 | -- 回滾到 UNSIGNED MAX +-------------------------+ mysql> SELECT 9223372036854775807 + 1; +-------------------------+ | 9223372036854775807 + 1 | +-------------------------+ | -9223372036854775808 | -- 回滾到 SIGNED MIN +-------------------------+
**無報錯、無警告**,結果邏輯錯誤但語法成功。
mysql> SELECT CAST(0 AS UNSIGNED) - 1; ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0 as unsigned) - 1)' mysql> SELECT 9223372036854775807 + 1; ERROR 1690 (22003): BIGINT value is out of range in '(9223372036854775807 + 1)'
**SQL 執行失敗**,錯誤碼 1690 (22003),數據完整性受保護。
sql_mode 可控制:NO_UNSIGNED_SUBTRACTION 等// Java 示例 if (balance < amount) throw new InsufficientBalanceException(); balance -= amount;
-- 觸發器防溢出
CREATE TRIGGER before_balance_update
BEFORE UPDATE ON account
FOR EACH ROW
BEGIN
IF NEW.balance < 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Balance cannot be negative';
END IF;
END;
DECIMAL(18,2) 而非整型分BIGINT(80 億年才用完)MySQL 5.7 Reference Manual: Out-of-Range and Overflow Handling