為什麼選 DECIMAL?
- 精確儲存:定點數,無浮點誤差(
0.1 + 0.2 = 0.3 而非 0.30000000000000004)
- 金融/金額/精度敏感業務 必選
- MySQL 5.1+ 支援
M ≤ 65,D ≤ 30 且 D ≤ M
語法與儲存空間
DECIMAL(M, D)
M = 精度(總位數,含小數點左右)
D = 標度(小數點右側位數)
儲存空間 ≈ M + 2 位元組(每 9 位數字壓縮為 4 位元組)
取值範圍速查
| 定義 | 最大值 | 最小值 | 說明 |
| DECIMAL(5,2) | 999.99 | -999.99 | 3 位整數 + 2 位小數 |
| DECIMAL(10,2) | 99999999.99 | -99999999.99 | 8 位整數,適合金額(億元級) |
| DECIMAL(15,4) | 99999999999.9999 | -99999999999.9999 | 高精度科學計算/匯率 |
| DECIMAL(65,30) | 最大範圍 | 最小範圍 | MySQL 允許極限 |
實測行為
CREATE TABLE ta (a FLOAT, b DECIMAL(10,5));
INSERT INTO ta VALUES (1, 12345.123423);
-- b 實際存入:12345.12342 (小數位超出截斷,不四捨五入)
INSERT INTO ta VALUES (1, 123456.1234);
-- b 實際存入:99999.99999 (整數位超出,截斷為最大值)
結論:
- 整數位超出範圍 → 截斷為最大值,小數位捨棄
- 小數位超出範圍 → 直接截斷(非四捨五入)
- 寫入前應用層驗證範圍,避免靜默截斷
對比:FLOAT/DOUBLE vs DECIMAL
| 類型 | 位元組 | 精度 | 適用場景 |
| FLOAT | 4 | ~7 位有效數字 | 科學計算、近似值、不需精確 |
| DOUBLE | 8 | ~15 位有效數字 | 高精度近似計算 |
| DECIMAL(10,2) | ~6 | 精確 10 位 | 金額、價格、庫存、比率 |
最佳實踐
- 金額欄位統一
DECIMAL(12,2) 或 DECIMAL(15,4)(多幣種匯率)
- 避免
FLOAT/DOUBLE 作為 WHERE 條件精確比較
- 應用層使用定點數庫(PHP:
brick/math, Java: BigDecimal, Python: decimal.Decimal)
- 索引:
DECIMAL 可建索引,範圍查詢走索引效能佳