MySQL 數據類型分類與選型策略深度解析
數據類型選型直接影響存儲成本、查詢性能與數據正確性。本文從四大類別劃分,結合實戰案例給出精準選型建議。
一、數字類型三大族群
1. 精確數字類:DECIMAL / NUMERIC
- 存儲:字符串形式,每位(含小數點)佔 1 字節
- 優勢:小數位固定,運算不「失真」
- 適用:價格、金額、匯率 等精度敏感業務
- 代價:空間佔用大,計算較慢
2. 浮點數類:FLOAT / DOUBLE
| 類型 | 精度 | 最小絕對值 | 存儲 |
| FLOAT | 單精度 | ~1.17E-38 | 4 字節 |
| DOUBLE | 雙精度 | ~2.22E-308 | 8 字節 |
- 適用:科學計算、地理坐標、物理常數等極值場景
- 民用業務極少用到:常規金額/比率用 DECIMAL 即可
3. 整數類:TINYINT → BIGINT
| 類型 | 存儲 | 無符號最大值 | 典型場景 |
| TINYINT | 1B | 255 | 年齡、狀態碼、布爾替代 |
| SMALLINT | 2B | 65,535 | 技能值、短整數業務 ID |
| MEDIUMINT | 3B | 16,777,215 | 千萬級自增主鍵首選 |
| INT | 4B | 4,294,967,295 | 通用自增主鍵、外鍵 |
| BIGINT | 8B | 18,446,744,073,709,551,615 | 分布式 ID、超大規模主鍵 |
選型鐵律:滿足業務上限的前提下,選佔用空間最小的類型。千萬級表用 MEDIUMINT 代替 INT,每行省 1B,千萬行省 10MB+。
二、日期時間類型
| 類型 | 範圍 | 存儲 | 選型建議 |
| DATE | 1000-01-01 ~ 9999-12-31 | 3B | 僅需日期:生日、生效日 |
| TIME | -838:59:59 ~ 838:59:59 | 3B | 僅需時間:營業時間、鬧鐘 |
| DATETIME | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | 8B | 通用日期時間:創建時間、訂單時間 |
| TIMESTAMP | 1970-01-01 ~ 2038-01-19 | 4B | 自動更新時間戳、跨時區業務 |
| YEAR | 1901 ~ 2155 | 1B | 年份:出生年、統計年 |
三、字符串類型:CHAR vs VARCHAR vs TEXT 族群
核心差異
| 類型 | 長度特性 | 實際存儲 | 最大長度 |
| CHAR(n) | 固定 | n 字節 | 255 |
| VARCHAR(n) | 可變 | 實際長度 + 1B | 65,535 (共享行上限) |
決策矩陣
- 固定長、高頻滿長 →
CHAR(如股票代碼 6 位、MD5 32 位、ISO 國家碼 2 位)
- 可變長、平均長度遠小於上限 →
VARCHAR(如用戶名、地址、評論)
- 「+1 字節」陷阱:VARCHAR 存儲長度前綴。若多數值接近上限,
VARCHAR(10) 實際 11B > CHAR(10) 10B
實戰案例:股票表
- 股票名稱:絕大多數 4 字(8B) →
CHAR(8)
- 股票代碼:滬市 6 位、深市 4 位,滬市佔比高 →
CHAR(6) 優於 VARCHAR(6)(深市 5B、滬市 7B,加權平均超過 6B)
TEXT 族群選型
| 類型 | 最大長度 | 長度前綴 | 適用場景 |
| TINYTEXT | 255 | 1B | 短文本:標籤、摘要 |
| TEXT | 64KB | 2B | 文章正文、評論內容 |
| MEDIUMTEXT | 16MB | 3B | 長文檔、日志詳情 |
| LONGTEXT | 4GB | 4B | 巨型文本、二進制序列化 |
四、枚舉與集合:極致壓縮的業務編碼
| 類型 | 成員上限 | 選擇規則 | 存儲 | 典型場景 |
| ENUM | 65,535 | 單選,必選一項 | 1-2B | 性別、狀態機、優先級 |
| SET | 64 | 多選,可零項 | 1-8B | 權限標籤、多屬性標記 |
性別字段最優解
-- 傳統:TINYINT(1) 0/1 需應用層映射
-- 最優:ENUM('帥哥','美眉')
-- 1 字節,直接存取字符串,可讀性極強
建庫策略總結
- 業務語義優先:類型要能表達業務含義(ENUM > TINYINT 表示狀態)
- 空間最小化:滿足上限前提下選最小類型
- 避免過度設計:大於 20 的 CHAR、大於 100 的 VARCHAR 幾乎不需要,直接上 TEXT
- 精度敏感用 DECIMAL:金額、價格、比率嚴禁 FLOAT/DOUBLE
- 時間選型:僅日期用 DATE,需時區用 TIMESTAMP,通用用 DATETIME