萬盛學電腦網

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

MySQL INT 數據類型長度誤區解析:M 顯示寬度 ≠ 儲存空間,ZEROFILL 與浮點數陷阱

MySQL 整數類型 INT(M) 中的 M **僅代表顯示寬度,不影響儲存空間、不限制數值範圍**。本文釐清 INT(M)、ZEROFILL、浮點數精度等常見誤區,並提供完整數值類型對照表與實測驗證代碼。

INT(M) 核心真相

  • 儲存空間固定 4 位元組:INT(3)、INT(4)、INT(8)、INT(11) 磁碟上皆佔 4 Bytes。
  • 數值範圍不變:有號 -2,147,483,648 ~ 2,147,483,647;無號 0 ~ 4,294,967,295。
  • M 僅影響顯示:搭配 ZEROFILL 時,左側補零至 M 位;否則 M 無任何實際作用。

ZEROFILL 實測演示

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) 僅作為「建議顯示寬度」給客戶端參考。

完整數值類型對照表

類型大小有號範圍無號範圍用途
TINYINT1 Byte-128 ~ 1270 ~ 255極小整數、布林替代
SMALLINT2 Bytes-32,768 ~ 32,7670 ~ 65,535小整數
MEDIUMINT3 Bytes-8,388,608 ~ 8,388,6070 ~ 16,777,215中整數
INT / INTEGER4 Bytes-2,147,483,648 ~ 2,147,483,6470 ~ 4,294,967,295標準整數
BIGINT8 Bytes-9.22e18 ~ 9.22e180 ~ 1.84e19極大整數、雪花 ID
FLOAT4 Bytes±3.4e38 (約 7 位有效數字)單精度浮點科學計算、非精確金額
DOUBLE8 Bytes±1.7e308 (約 15 位有效數字)雙精度浮點高精度科學計算
DECIMAL(M,D)M+2 或 D+2 Bytes精確定點數,最多 65 位數字精確定點數金額、財務、精確計算

浮點數精度陷阱 (FLOAT/DOUBLE)

二進位無法精確表示十進位小數

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 |  -- 近似值!
+------------+

金額欄位**嚴禁使用 FLOAT/DOUBLE**

  • 改用 DECIMAL(10,2) (整數 8 位 + 小數 2 位) 或 BIGINT 存分/厘 (乘 100/1000)。
  • 應用層以整數運算,顯示時除以 100 格式化。

DECIMAL(M,D) 長度含義

  • M = 總位數 (精度),D = 小數位數 (標度)。
  • DECIMAL(4,1) 允許 999.9,插入 1234 → 存為 999.9 (超出範圍截斷並警告)。
  • 儲存空間:每 9 位數字 4 字節,餘數對照表分配。

PHP/C/C++ 整數溢出對應

語言/平台INT 大小最大值溢出行為
PHP 32-bit4 Bytes2,147,483,647超過自動轉 float
PHP 64-bit8 Bytes9,223,372,036,854,775,807極大,幾乎不溢出
C/C++ 32-bit (signed int/long)4 Bytes2,147,483,647未定義行為 (繞回負數)
C/C++ 64-bit (long)8 Bytes9.22e18同上

對策: 使用 PHP_INT_MAX、INT64_MAX、int64_t、BIGINT、DECIMAL 明確表達大整數需求,避免隱式轉換導致邏輯錯誤。

總結

  1. INT(M) 的 M **只影響 ZEROFILL 顯示**,不影響儲存、範圍、索引。
  2. 金額/精確計算 **只用 DECIMAL 或整數(分/厘)**,永不使用 FLOAT/DOUBLE。
  3. 跨語言/平台交互時,**明確協定整數大小與編碼**,防止溢出與精度損失。
copyright © 萬盛學電腦網 all rights reserved