MySQL 支持數值、日期時間、字符串三大類型,每類含多個子類型。正確選型 = 空間最優 + 精度保證 + 查詢高效。
| 類型 | 存儲 | 有符號範圍 | 無符號範圍 | 典型場景 |
|---|---|---|---|---|
| TINYINT | 1B | -128 ~ 127 | 0 ~ 255 | 布爾值、狀態碼、極小計數 |
| SMALLINT | 2B | -32,768 ~ 32,767 | 0 ~ 65,535 | 小範圍計數、年齡、短整數 |
| MEDIUMINT | 3B | -8,388,608 ~ 8,388,607 | 0 ~ 16,777,215 | 中等計數、RGB 顏色值 |
| INT / INTEGER | 4B | -2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 | 通用 ID、計數器、IP 存儲 |
| BIGINT | 8B | -9.22E18 ~ 9.22E18 | 0 ~ 1.84E19 | 大數據 ID、時間戳毫秒、高精度計算 |
關鍵點:INT(M) 中 M 僅為顯示寬度(ZEROFILL 時補 0),不影響存儲範圍。非負場景優先 UNSIGNED 翻倍範圍。
| 類型 | 存儲 | 精度 | 適用場景 |
|---|---|---|---|
| FLOAT(M,D) | 4B | ~7 位有效數字 | 科學計算、近似值、空間坐標 |
| DOUBLE(M,D) | 8B | ~15 位有效數字 | 高精度科學計算 |
| DECIMAL(M,D) / NUMERIC | 變長 | 精確(字符串存儲) | 金額、價格、比率、任何不可損失精度場景 |
鐵律:涉及金錢、精確比率,只能用 DECIMAL。FLOAT/DOUBLE 二進制無法精確表示 0.1 等十進制小數,會產生 0.30000000000000004 類誤差。
| 類型 | 最大長度 | 存儲特點 | 適用場景 |
|---|---|---|---|
| CHAR(M) | 255 字符 | 定長,右側空格填充 | 固定長度代碼:MD5、UUID、國標代碼 |
| VARCHAR(M) | 65,535 字符 | 變長,1-2B 存長度 | 通用變長文本:名稱、描述、URL |
| TINYTEXT | 255 B | 不計入行長度限制 | 極短文本 |
| TEXT | 64 KB | 同上 | 文章、日志、中等文本 |
| MEDIUMTEXT | 16 MB | 同上 | 長文本 |
| LONGTEXT | 4 GB | 同上 | 超大文本、文檔存儲 |
| BINARY/VARBINARY | 同 CHAR/VARCHAR | 二進制字節流,無字符集 | 加密數據、圖片哈希、序列化對象 |
| BLOB 系列 | 同 TEXT 系列 | 二進制大對象 | 文件存儲(不推薦,用對象存儲) |
| 類型 | 存儲 | 範圍 | 特性 |
|---|---|---|---|
| DATETIME | 8B | 1000-01-01 ~ 9999-12-31 | 無時區,靜態時間點 |
| TIMESTAMP | 4B | 1970-01-01 ~ 2038-01-19 | 時區感知,自動更新(DEFAULT/ON UPDATE CURRENT_TIMESTAMP) |
| DATE | 3B | 1000-01-01 ~ 9999-12-31 | 純日期 |
| TIME | 3B | -838:59:59 ~ 838:59:59 | 純時間/時長 |
| YEAR | 1B | 1901 ~ 2155 | 年份 |
建議:業務時間用 TIMESTAMP(自動維護、節省空間),歷史/未來時間用 DATETIME。應用層統一 UTC 存儲,展示層轉時區。
SMALLINT 索引。缺陷:新增值需 DDL、默認值陷阱(非法值存空串)、數字插入被當索引處理。替代:TINYINT + 應用層字典/檢查約束。BIGINT 位掩碼。替代:關聯表或 JSON 字段(5.7+)。
-- IPv4: INT UNSIGNED (4B)
INSERT INTO ip_log(ip) VALUES (INET_ATON('192.168.1.1')); -- 3232235777
SELECT INET_NTOA(ip) FROM ip_log; -- '192.168.1.1'
-- PHP 對接
$ipLong = sprintf("%u", ip2long('192.168.1.1')); // 無符號
$ipStr = long2ip($ipLong);
按「功能滿足 → 空間最小 → 處理最高效 → 兼容性」優先級選型,是資深 DBA 與開發的共識。