數值類型全景圖
| 分類 | 類型 | 存儲字節 | 有符號範圍 | 無符號範圍 | 核心特點 |
| 整數 | TINYINT | 1 | -128 ~ 127 | 0 ~ 255 | 極小範圍,狀態碼、布爾、年齡 |
| SMALLINT | 2 | -32,768 ~ 32,767 | 0 ~ 65,535 | 較小範圍,郵編、中小表主鍵 |
| MEDIUMINT | 3 | -8,388,608 ~ 8,388,607 | 0 ~ 16,777,215 | 中等範圍,千萬級表自增主鍵首選 |
| INT / INTEGER | 4 | -2.14B ~ 2.14B | 0 ~ 4.29B | 通用標準,大多數自增主鍵 |
| BIGINT | 8 | -9.22E18 ~ 9.22E18 | 0 ~ 1.84E19 | 超大範圍,分布式 ID、時間戳毫秒 |
| 浮點數 | FLOAT | 4 | ±1.17E-38 ~ ±3.4E38 | - | 單精度,約 7 位有效數字,科學計算 |
| DOUBLE | 8 | ±2.22E-308 ~ ±1.79E308 | - | 雙精度,約 15 位有效數字,精度要求高 |
| 定點數 | DECIMAL(M,D) | M/2+2 (約) | 精確到 D 位小數 | - | 字符串存儲,無精度損失,金額、價格必用 |
| NUMERIC | 同 DECIMAL | 同 DECIMAL | 同 DECIMAL | 同義詞 |
| 位類型 | BIT(N) | ≈N/8 | 位向量 | - | 標誌位組合、權限掩碼 |
選型決策原則
是否涉及金額/精確計算?
├─ 是 → DECIMAL(precision, scale) -- 如 DECIMAL(10,2) 支持 99,999,999.99
└─ 否 → 是否為整數?
├─ 是 → 最大值多大?
├─ ≤ 255 → TINYINT UNSIGNED
├─ ≤ 65,535 → SMALLINT UNSIGNED
├─ ≤ 16.7M → MEDIUMINT UNSIGNED
├─ ≤ 4.29B → INT UNSIGNED
└─ > 4.29B → BIGINT UNSIGNED
└─ 否 → 科學計算/幾何/統計?
├─ 精度要求一般 → FLOAT
└─ 高精度/累加誤差敏感 → DOUBLE
實戰案例:空間節省效應
-- 場景:1 億行訂單表,主鍵 ID 最大 2000 萬
-- 方案 A:BIGINT (8 字節) → 800 MB 純主鍵空間
-- 方案 B:INT UNSIGNED (4 字節) → 400 MB,節省 50%
-- 方案 C:MEDIUMINT UNSIGNED (3 字節) → 300 MB,再省 25%
-- 附帶索引節省更巨大:B+ 樹非葉節點只存主鍵,縮小 50% 意味著
-- 內存能緩存 2 倍索引節點,磁盤 I/O 減半,備份恢復加倍快
DECIMAL 精度與存儲計算
- 每 4 個十進制位數打包為 2 字節(9 位用 4 字節)
- 整數部分位數 = M - D,小數部分 = D
- 存儲字節 = CEIL(整數位/9)*2 + CEIL(小數位/9)*2
- 例:
DECIMAL(19,4) → 整數 15 位(2塊=4字節) + 小數 4 位(1塊=2字節) = 6 字節
常見誤區與避坑
| 誤區 | 後果 | 正確做法 |
| 習慣性用 BIGINT 做主鍵 | 空間浪費 2-4 倍,索引膨脹,緩存命中率降 | 按業務上界選最小滿足類型 |
| 用 FLOAT/DOUBLE 存價格 | 0.1 + 0.2 ≠ 0.3,對賬永遠差幾分 | 強制 DECIMAL(10,2) 或更高精度 |
| INT(11) 以為限制長度 | 顯示寬度不影響存儲範圍,仍佔 4 字節 | 忽略顯示寬度,關注類型本身 |
| 無符號未聲明 UNSIGNED | 負數空間浪費一半,業務不允許負值 | 所有非負業務列加 UNSIGNED |
| BIT 類型當布爾用 | BIT(1) 存儲 1 字節,不如 TINYINT(1) 直觀 | 布爾用 TINYINT(1) 或 BOOLEAN 別名 |
顯示寬度與 ZEROFILL
-- INT(5) ZEROFILL 插入 42 → 存儲 42,SELECT 顯示 '00042'
-- 僅影響客戶端顯示,不影響存儲、計算、索引
-- 生產環境建議不使用,應用層格式化更靈活
類型修改風險
-- 擴大類型:安全,數據不丟失
ALTER TABLE t MODIFY col BIGINT;
-- 縮小類型:風險!超出範圍數據會被截斷或報錯
ALTER TABLE t MODIFY col SMALLINT; -- 可能截斷
-- 修改前必須檢查
SELECT MAX(col), MIN(col) FROM t;
-- 確認在目標類型範圍內再操作
數值類型選型是「剛好夠用」的藝術。每個字節在億級表中都會被放大成 GB 級差異,養成「先估上界、再選最小、必加 UNSIGNED、金額用 DECIMAL」的肌肉記憶,是資深工程師的基本功。