MySQL 提供豐富的資料類型,正確選型不僅能節省儲存空間,更能提升查詢效能並避免隱性轉換陷阱。本文系統整理數值、字串、日期時間、複合類型的儲存需求、範圍、適用場景與常見誤區,供開發與 DBA 參考。
| 類型 | 位元組 | 有符號範圍 | 無符號範圍 | 典型用途 |
|---|---|---|---|---|
| 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 / INTEGER | 4 | -2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 | 通用主鍵、計數器 |
| BIGINT | 8 | -9.22e18 ~ 9.22e18 | 0 ~ 1.84e19 | 極大整數、分散式 ID、時間戳毫秒 |
顯示寬度誤區: INT(6) 僅影響客戶端顯示時的零填充(搭配 ZEROFILL),不限制儲存範圍。插入超出範圍的值會被截斷並產生警告;非法值(如字串插入整數欄)會被轉為 0。
修飾符:
UNSIGNED:捨棄符號位,正數範圍翻倍。ZEROFILL:不足寬度時左補 0(而非空格),隱含 UNSIGNED。| 類型 | 位元組 | 精度 | 適用場景 |
|---|---|---|---|
| FLOAT(M,D) | 4 | 單精度(約 7 位有效數字) | 科學計算、近似值、儲存空間敏感 |
| DOUBLE(M,D) | 8 | 雙精度(約 15 位有效數字) | 較高精度近似計算 |
| DECIMAL(M,D) | M+2 或 D+2 | 精確定點,按字串儲存每位數字 | 金融金額、精確計量、任何不能有捨入誤差的場景 |
關鍵差異: FLOAT/DOUBLE 為二進制近似表示,0.1 + 0.2 != 0.3;DECIMAL 以 BCD 字串儲存,數學運算精確。DECIMAL(10,2) 可儲存 99999999.99。省略 M,D 預設為 DECIMAL(10,0)(整數)。
| 類型 | 最大長度 | 儲存特性 | 適用場景 |
|---|---|---|---|
| CHAR(M) | 255 字元 | 定長,右補空格 | 固定長度代碼(MD5、UUID、國家代碼) |
| VARCHAR(M) | 65,535 字元(共享 64KB 行上限) | 變長,額外 1~2 位元組記錄長度 | 不定長文字、名稱、描述 |
| TINYTEXT / TINYBLOB | 255 位元組 | 不區分大小寫 / 區分大小寫 | 極短文本/二進制 |
| TEXT / BLOB | 64 KB | 同上 | 文章內容、JSON、小圖片 |
| MEDIUMTEXT / MEDIUMBLOB | 16 MB | 同上 | 長文本、較大二進制 |
| LONGTEXT / LONGBLOB | 4 GB | 同上 | 巨大文件、完整日誌 |
| BINARY(M) / VARBINARY(M) | M 位元組 | 二進制定長/變長,無字元集概念 | 加密資料、哈希值、檔案片段 |
CHAR vs VARCHAR 核心差異:
CHAR 固定佔用 M 字元,不足補空格,讀取時尾部空格被移除(除非 PAD_CHAR_TO_FULL_LENGTH SQL 模式)。VARCHAR 僅佔用實際長度 + 1~2 位元組長度前綴,不補空格,讀取保留尾部空格。UPDATE 導致長度變化的欄位用 VARCHAR 可減少碎片;極短且固定長度用 CHAR 索引效能略優。TEXT/BLOB 限制: 不支援 DEFAULT 值,索引需指定前綴長度(INDEX idx_title (title(50))),且無法放入內存臨時表(會強制磁碟臨時表),影響效能。
| 類型 | 位元組 | 範圍 | 格式 | 特性 |
|---|---|---|---|---|
| DATE | 4 | 1000-01-01 ~ 9999-12-31 | YYYY-MM-DD | 純日期 |
| TIME | 3 | -838:59:59 ~ 838:59:59 | HH:MM:SS | 時間或持續時間 |
| YEAR | 1 | 1901 ~ 2155 | YYYY | 年份,2 位數自動轉 4 位(00-69→2000-2069,70-99→1970-1999) |
| DATETIME | 8 | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 無時區感知,佔用固定 8 位元組 |
| TIMESTAMP | 4 | 1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC | YYYY-MM-DD HH:MM:SS | 時區感知,儲存 UTC,讀取轉換為會話時區;首個 TIMESTAMP 欄位預設 CURRENT_TIMESTAMP 且 ON UPDATE CURRENT_TIMESTAMP |
選型建議: 5.6.4+ 版本 DATETIME 支援微秒精度(DATETIME(6)),且無 2038 年問題,優先考慮 DATETIME;需自動記錄建立/更新時間且跨時區應用才用 TIMESTAMP。
| 類型 | 儲存方式 | 最大元素 | 特性 |
|---|---|---|---|
| ENUM('v1','v2',...) | 1~2 位元組整數索引(1 起) | 65,535 | 單選,非法值插入空字串(索引 0),大小寫自動修正匹配 |
| SET('v1','v2',...) | 位元組位圖(最多 8 位元組) | 64 | 多選,自動去重、忽略非法元素,儲存為位掩碼 |
效能提示: ENUM/SET 內部以整數儲存,排序按定義順序而非字面值;ORDER BY enum_col 會按索引排序,若需字母序需 ORDER BY CAST(enum_col AS CHAR)。避免在 ENUM 中存儲數字字串(如 '1','2','3'),易混淆索引與值。
TINYINT 別用 INT。DECIMAL,禁止 FLOAT/DOUBLE。VARCHAR,長度設業務實際上限而非 255/65535。DATETIME(6),跨時區才用 TIMESTAMP。TINYINT + 應用層字典或 ENUM,避免魔術數字。掌握類型特性,能在 Schema 設計階段就為效能與正確性奠基。建議收藏備查,並在 Code Review 時檢視類型選擇是否合理。