MySQL 提供豐富的數據類型,正確選型直接影響存儲效率、索引性能、數據完整性。本文整理 **數值類型 (整數/浮點/定點)、日期時間、字符串、二進制大對象、枚舉/集合** 完整取值範圍、存儲字節、適用場景與選型原則,做桌面速查卡。
| 類型 | 存儲 (Bytes) | 有符號範圍 | 無符號範圍 (UNSIGNED) | 典型場景 |
|---|---|---|---|---|
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 | 中等計數、IPv4 存儲 (INT UNSIGNED 更常用) |
INT / INTEGER | 4 | -2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 | **通用主鍵 ID、計數器、外鍵** (首選) |
BIGINT | 8 | -9.22E18 ~ 9.22E18 | 0 ~ 1.84E19 | 超大主鍵 (分布式 ID、雪花算法)、大計數 |
選型原則:夠用就行,越小越好。主鍵優先 BIGINT UNSIGNED (防耗盡) 或 INT UNSIGNED (單表 < 40 億);狀態/標誌用 TINYINT UNSIGNED;避免指定顯示寬度 (如 INT(11)),MySQL 8.0 已棄用,不影響存儲範圍。
| 類型 | 存儲 | 範圍 (近似) | 精度 | 適用場景 |
|---|---|---|---|---|
FLOAT (單精度) | 4 Bytes | ±1.17E-38 ~ ±3.40E+38 | ~7 位有效數字 | 科學計算、非精確測量、坐標 (可接受誤差) |
DOUBLE / REAL (雙精度) | 8 Bytes | ±2.22E-308 ~ ±1.79E+308 | ~15-17 位有效數字 | 高精度科學計算、地理空間 |
DECIMAL(M,D) / NUMERIC(M,D) | M+2 Bytes (約) | 由 M,D 決定,最大 65 位數字 | **精確到小數點後 D 位** | 金額、價格、匯率、庫存、任何不能有誤差的業務數據 |
鐵律:**貨幣/金額/庫存 必用 DECIMAL**。FLOAT/DOUBLE 為二進制浮點,0.1 + 0.2 != 0.3,財務系統嚴禁使用。
| 類型 | 存儲 | 範圍 | 精度 | 時區感知 | 典型場景 |
|---|---|---|---|---|---|
DATE | 3 Bytes | 1000-01-01 ~ 9999-12-31 | 天 | 否 | 生日、入職日期、訂單日期 |
DATETIME | 8 Bytes (5.6.4 前) / 5+Bytes (5.6.4+) | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | 秒 (可擴展微秒 .ffffff) | 否 | 業務時間、日志記錄、創建/更新時間 (不跨時區) |
TIMESTAMP | 4 Bytes | 1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC | 秒 (可擴展微秒) | 是 (存儲 UTC,讀取按會話時區轉換) | 跨時區應用、自動更新列 (ON UPDATE CURRENT_TIMESTAMP) |
TIME | 3 Bytes | -838:59:59 ~ 838:59:59 | 秒 (可擴展微秒) | 否 | 耗時、班次時間、每日定時任務 |
YEAR | 1 Byte | 1901 ~ 2155 (4位) / 1970-2069 (2位) | 年 | 否 | 年份統計、車型年款 |
選型決策樹:
需要時區轉換/自動更新 → TIMESTAMP (注意 2038 年問題)
不需要時區、範圍大、手動設置 → DATETIME (推薦通用)
僅日期 → DATE
僅時間/間隔 → TIME
| 類型 | 最大長度 | 存儲特點 | 大小寫敏感 | 尾部空格處理 | 典型場景 |
|---|---|---|---|---|---|
CHAR(M) [BINARY] | 255 字符 | 固定長度,右側填充空格 | 無 BINARY 不敏感 | 讀取時自動去除 | 固定長度代碼 (MD5、UUID、ISO 代碼、手機號) |
VARCHAR(M) [BINARY] | 255 (≤5.0.3) / 65,535 (5.0.3+) | 變長,1-2 字節長度前綴 + 實際內容 | 無 BINARY 不敏感 | 保留 (不填充不截斷) | **通用變長文本** (姓名、標題、地址、JSON 片段) |
TINYTEXT | 255 (2^8-1) | 變長,無默認值,不可整列索引 | 不敏感 | 保留 | 極短文本 (標籤、備註) |
TEXT | 65,535 (2^16-1) | 同上 | 不敏感 | 保留 | 文章正文、日志、中等文本 |
MEDIUMTEXT | 16,777,215 (2^24-1) | 同上 | 不敏感 | 保留 | 長文本、文檔 |
LONGTEXT | 4,294,967,295 (2^32-1) | 同上 | 不敏感 | 保留 | 超長文本、完整文檔存儲 |
關鍵差異:CHAR 固定長度適合極短、固定、頻繁更新的列 (避免碎片);VARCHAR 變長節省空間,首選通用文本類型;TEXT 族群無法設默認值、索引需指定前綴長度、不在內存臨時表 (會落盤),性能較差,**能用 VARCHAR 就不用 TEXT**。
| 類型 | 最大長度 (Bytes) | 對應文本類型 | 典型場景 |
|---|---|---|---|
TINYBLOB | 255 | TINYTEXT | 極小二進制 (圖標、縮略圖) |
BLOB | 65,535 | TEXT | 圖片、文檔、序列化對象 |
MEDIUMBLOB | 16,777,215 | MEDIUMTEXT | 大文件、視頻片段 |
LONGBLOB | 4,294,967,295 | LONGTEXT | 超大文件、備份映像 |
最佳實踐:數據庫**不建議存大文件**。存對象存儲 (S3/OSS/MinIO) 路徑/URL,DB 僅存 VARCHAR(512) 路徑 + 元數據。若必須存 DB,用 BLOB 族群,設置 max_allowed_packet 足夠大。
| 類型 | 定義語法 | 成員上限 | 存儲 | 典型場景 |
|---|---|---|---|---|
ENUM('v1','v2',...) | 單選,最多 65,535 個不同值 | 65,535 | 1-2 Bytes (索引值) | 狀態機 (pending/paid/shipped/cancelled)、性別、固定分類 |
SET('v1','v2',...) | 多選,最多 64 個成員 | 64 | 1-8 Bytes (位圖) | 權限標籤、多屬性標記 (tag1,tag3,tag5) |
優缺點:
✅ 存儲極小、內建約束、可讀性強
❌ 修改成員需 ALTER TABLE (鎖表)、不可用於外鍵、排序按索引值而非字符串、遷移異構 DB 麻煩
建議:穩定、少量、極少變更 的枚舉集合可用;其餘改用 TINYINT UNSIGNED + 應用層常量/字典表,靈活性高得多。
| 業務需求 | 推薦類型 | 備選/避坑 |
|---|---|---|
| 主鍵 ID (單表 < 40 億) | BIGINT UNSIGNED AUTO_INCREMENT / INT UNSIGNED | 避免 INT(11) 顯示寬度 |
| 分布式唯一 ID (雪花/UUID) | BIGINT UNSIGNED / CHAR(36) (UUID) / BINARY(16) (UUID 二進制) | CHAR(36) 佔空間大、索引慢 |
| 金額/價格/匯率 | DECIMAL(19,4) / DECIMAL(10,2) | 嚴禁 FLOAT/DOUBLE |
| 創建時間/更新時間 | DATETIME(3) / TIMESTAMP(3) (需時區) | 默認值 CURRENT_TIMESTAMP(3)、更新 ON UPDATE CURRENT_TIMESTAMP(3) |
| 用戶姓名/標題/地址 | VARCHAR(100/200/500) CHARSET utf8mb4 | 避免 TEXT |
| 文章正文/長文本 | MEDIUMTEXT / LONGTEXT | 考慮對象存儲 + 路徑 |
| 圖片/文件二進制 | 對象存儲 + VARCHAR(512) 路徑 | 必存 DB 用 BLOB,調大 max_allowed_packet |
| 訂單狀態/性別/類型 | TINYINT UNSIGNED + 應用層常量 | 穩定極少變可用 ENUM |
| 標籤/多屬性 | JSON (5.7+) / 關聯表 tag_map | SET 限 64 個、難擴展 |
數據類型選型是架構設計的基石。**「整數優先 BIGINT/INT、金額必用 DECIMAL、時間通用 DATETIME、文本首選 VARCHAR、大對象外存、枚舉慎用 ENUM/SET」**——將這句口訣貼在顯示器邊,每次建表默念三遍,能避開 90% 的存儲與性能坑。