核心結論先行
- FLOAT/DOUBLE 為近似數值類型,不適合財務、金額等要求精確計算的場景 → 請使用 DECIMAL。
- 定義語法
FLOAT(M,D) / DOUBLE(M,D):M 為總位數(含小數點前後),D 為小數位數。
- MySQL 存儲時會四捨五入,超出範圍報錯
ERROR 1264 (22003)。
實測驗證:FLOAT(9,3)
CREATE TABLE tt (num FLOAT(9,3));
INSERT INTO tt VALUES (1234567.8); -- ERROR 1264: 整數部超過 6 位(9-3=6)
INSERT INTO tt VALUES (123456.8); -- OK,存入 123456.797(二進制近似)
INSERT INTO tt VALUES (123456.867); -- OK,存入 123456.867
INSERT INTO tt VALUES (2.8); -- OK,存入 2.800
INSERT INTO tt VALUES (2.888888); -- OK,存入 2.889(四捨五入)
SELECT * FROM tt WHERE num = 2.8; -- 命中 2.800
SELECT * FROM tt WHERE num = 123456.8; -- 無結果!實際存 123456.797
實測驗證:DOUBLE(9,3)
CREATE TABLE tt (num DOUBLE(9,3));
INSERT INTO tt VALUES (234563.9); -- OK
INSERT INTO tt VALUES (2345623.2); -- ERROR 1264: 整數部超過 6 位
INSERT INTO tt VALUES (2.8); -- OK,2.800
精度陷阱示意
| 插入值 | FLOAT(9,3) 實際存儲 | 說明 |
| 123456.8 | 123456.797 | 二進制無法精確表示 0.8,產生近似值 |
| 0.12 | 0.120 | 若未指定 (M,D),預設精度不足導致查詢失效 |
| 2.888888 | 2.889 | 超出 D=3 自動四捨五入 |
避坑指南
- 精確計算場景(金額、庫存、比率)必須用
DECIMAL(M,D),定點數無精度損失。
- 查詢浮點數欄位時,避免直接
= 比較,改用範圍:
WHERE num BETWEEN 123456.79 AND 123456.81
- 建表時顯式指定 (M,D),避免預設精度導致資料截斷或查詢失效。
- DOUBLE 精度較 FLOAT 高(約 15 位有效數字),但同樣屬近似類型,原則同上。
- 科學計算、座標、感測器數據等容忍微小誤差的場景可用 FLOAT/DOUBLE,節省空間(4/8 bytes vs DECIMAL 可變長)。
儲存空間對照
| 類型 | 位元組 | 有效數字 | 適用場景 |
| FLOAT | 4 | ~7 位 | 科學計算、圖形座標、近似統計 |
| DOUBLE | 8 | ~15 位 | 高精度科學計算、GPS 座標 |
| DECIMAL(M,D) | M/2+2 約略 | 精確到 D 位 | 財務、金額、庫存、比率計算 |