核心原則:越小越好、越簡單越好、盡量 NOT NULL
資料型別直接決定儲存空間、索引大小、快取效率與 CPU 比較開銷。本文從實戰角度梳理型別選擇黃金法則。
一、數值型別:精準定級,拒絕浪費
| 型別 | 儲存 | 範圍(無號) | 適用場景 |
| TINYINT | 1B | 0-255 | 狀態碼、布林、小枚舉 |
| SMALLINT | 2B | 0-65535 | 中小型字典表 ID |
| MEDIUMINT | 3B | 0-1677萬 | 中型業務表主鍵 |
| INT | 4B | 0-42億 | 通用主鍵、外鍵 |
| BIGINT | 8B | 0-2^64 | 極大量資料、分散式 ID |
- 非負欄位加 UNSIGNED:正數上限翻倍,零成本。
- 拒絕 DOUBLE/FLOAT 存金額:精度陷阱。定點數 乘固定倍數 (如 *100) 轉 BIGINT 儲存,查詢時除以倍數。
- 慎用 DECIMAL:同理,轉整數更高效。
二、字串型別:定長變長分明,長度恰好
- CHAR(n):定長,補空格。適用
MD5、UUID、手機號、身分證 等固定長度值。不存 NULL 時效能最高。
- VARCHAR(n):變長,1-2 bytes 存長度。n 設業務實際上限 (如手機
VARCHAR(11)),過大影響記憶體臨時表與排序緩存。
- 拒絕 TEXT/BLOB:行溢位存儲、無法建完整索引、臨時表落盤、效能極差。大文本拆獨立表或用對象儲存。
三、日期時間:原生型別最強
| 型別 | 儲存 | 範圍 | 建議 |
| DATE | 3B | 1000-01-01 ~ 9999-12-31 | 僅需日期,最省空間 |
| TIMESTAMP | 4B | 1970-2038 | 時區感知,自動更新,次選 |
| DATETIME | 8B | 1000-9999 | 需超出 TIMESTAMP 範圍或不想時區轉換 |
- 拒絕 INT 存 Unix Timestamp:可讀性差、時區處理麻煩、無效能優勢。
四、特殊型別:ENUM/SET 是狀態欄位神器
- ENUM:1-2 bytes,內部存數值。單選狀態 (性別、訂單狀態、支付方式)。
ALTER TABLE t MODIFY col ENUM('a','b','c') 末尾新增值無需重建表。
- SET:1-8 bytes,位元組合。多選屬性 (標籤、權限)。位元運算極快。
五、PROCEDURE ANALYSE() 讓資料庫幫你建議型別
SELECT * FROM table_name PROCEDURE ANALYSE(16, 256);
-- 16: 最大枚舉值個數,256: 每欄最大記憶體
-- 輸出欄位 Optimal_fieldtype 給出建議型別
根據建議配合 ALTER TABLE ... MODIFY COLUMN ... 調整型別。
六、多欄索引與雜湊索引技巧
- 組合索引最左前綴原則:高選擇性欄位靠左。
- BLOB/長字串建雜湊索引:
ADD COLUMN hash_val CHAR(32), ADD INDEX(hash_val),存 MD5(col),精確查詢走雜湊索引,避免全文掃描。
- 大欄位垂直拆分:熱欄位留主表,冷大欄位移副表 (一對一),主表變窄 → 單頁行數增 → IO 降、快取升。
總結清單
- 數值:能用 TINYINT 不用 INT,能用 UNSIGNED 就加。
- 字串:固定長度用 CHAR,變長用 VARCHAR 設精確上限,拒 TEXT/BLOB。
- 時間:優先 DATE/TIMESTAMP,拒 INT。
- 狀態:優先 ENUM/SET。
- 大欄位:垂直拆分或雜湊索引。
- 所有欄位:預設 NOT NULL + DEFAULT 值。