MySQL 整數類型 INT(M) 中的 M **僅代表顯示寬度,不影響儲存空間、不限制數值範圍**。本文釐清 INT(M)、ZEROFILL、浮點數精度等常見誤區,並提供完整數值類型對照表與實測驗證代碼。
INT(3)、INT(4)、INT(8)、INT(11) 磁碟上皆佔 4 Bytes。ZEROFILL 時,左側補零至 M 位;否則 M 無任何實際作用。CREATE TABLE test (
id INT(3) UNSIGNED ZEROFILL AUTO_INCREMENT PRIMARY KEY
);
INSERT INTO test VALUES (NULL), (NULL), (NULL);
SELECT * FROM test;
+------+
| id |
+------+
| 001 |
| 002 |
| 003 |
+------+
-- 超過寬度不截斷
INSERT INTO test VALUES (1234);
SELECT * FROM test;
+------+
| id |
+------+
| 001 |
| 002 |
| 003 |
| 1234 | -- 顯示完整,不截斷
+------+
無 ZEROFILL 時: 正常顯示 1, 10, 1234,INT(3) 僅作為「建議顯示寬度」給客戶端參考。
| 類型 | 大小 | 有號範圍 | 無號範圍 | 用途 |
|---|---|---|---|---|
| TINYINT | 1 Byte | -128 ~ 127 | 0 ~ 255 | 極小整數、布林替代 |
| SMALLINT | 2 Bytes | -32,768 ~ 32,767 | 0 ~ 65,535 | 小整數 |
| MEDIUMINT | 3 Bytes | -8,388,608 ~ 8,388,607 | 0 ~ 16,777,215 | 中整數 |
| INT / INTEGER | 4 Bytes | -2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 | 標準整數 |
| BIGINT | 8 Bytes | -9.22e18 ~ 9.22e18 | 0 ~ 1.84e19 | 極大整數、雪花 ID |
| FLOAT | 4 Bytes | ±3.4e38 (約 7 位有效數字) | 單精度浮點 | 科學計算、非精確金額 |
| DOUBLE | 8 Bytes | ±1.7e308 (約 15 位有效數字) | 雙精度浮點 | 高精度科學計算 |
| DECIMAL(M,D) | M+2 或 D+2 Bytes | 精確定點數,最多 65 位數字 | 精確定點數 | 金額、財務、精確計算 |
7.22、0.1 等十進位小數在 IEEE 754 二進位浮點中為無限循環,存儲時發生捨入誤差。
mysql> CREATE TABLE t (f FLOAT(9,3));
mysql> INSERT INTO t VALUES (123456.8);
mysql> SELECT * FROM t;
+------------+
| f |
+------------+
| 123456.797 | -- 近似值!
+------------+
DECIMAL(10,2) (整數 8 位 + 小數 2 位) 或 BIGINT 存分/厘 (乘 100/1000)。M = 總位數 (精度),D = 小數位數 (標度)。DECIMAL(4,1) 允許 999.9,插入 1234 → 存為 999.9 (超出範圍截斷並警告)。| 語言/平台 | INT 大小 | 最大值 | 溢出行為 |
|---|---|---|---|
| PHP 32-bit | 4 Bytes | 2,147,483,647 | 超過自動轉 float |
| PHP 64-bit | 8 Bytes | 9,223,372,036,854,775,807 | 極大,幾乎不溢出 |
| C/C++ 32-bit (signed int/long) | 4 Bytes | 2,147,483,647 | 未定義行為 (繞回負數) |
| C/C++ 64-bit (long) | 8 Bytes | 9.22e18 | 同上 |
對策: 使用 PHP_INT_MAX、INT64_MAX、int64_t、BIGINT、DECIMAL 明確表達大整數需求,避免隱式轉換導致邏輯錯誤。
INT(M) 的 M **只影響 ZEROFILL 顯示**,不影響儲存、範圍、索引。