數據類型 vs 列類型
- 數據類型:值的抽象分類(數值、字符串、日期、NULL)
- 列類型:
CREATE TABLE 時具體聲明的存儲格式(如 INT UNSIGNED、VARCHAR(100)、DATETIME),含長度、屬性、約束
數值列類型詳細表
| 類型 | 有符號範圍 | 無符號範圍 | 存儲 | 適用場景 |
| TINYINT | -128 ~ 127 | 0 ~ 255 | 1B | 狀態碼、布爾、年齡 |
| SMALLINT | -32,768 ~ 32,767 | 0 ~ 65,535 | 2B | 郵編、小計數器 |
| MEDIUMINT | -8,388,608 ~ 8,388,607 | 0 ~ 16,777,215 | 3B | 中等計數、顏色 RGB |
| INT / INTEGER | -2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 | 4B | 通用 ID、外鍵、計數 |
| BIGINT | -9.22E18 ~ 9.22E18 | 0 ~ 1.84E19 | 8B | 巨大 ID、時間戳毫秒 |
| FLOAT(M,D) | ±1.175E-38 ~ ±3.402E+38 | — | 4B | 單精度科學計算 |
| DOUBLE(M,D) | ±2.225E-308 ~ ±1.797E+308 | — | 8B | 雙精度科學/金融 |
| DECIMAL(M,D) | 精確定點,M≤65,D≤30 | — | M+2B | 貨幣、精確計量(首選) |
選型鐵律:滿足業務範圍的**最小類型**。
- 整數優先 UNSIGNED 獲得雙倍正向範圍
- AUTO_INCREMENT 必須配合整數類型
- 科學計算用 DOUBLE,**金融嚴禁浮點**,必用 DECIMAL
字符串列類型詳細表
| 類型 | 最大長度 | 存儲開銷 | 特點 | 適用場景 |
| CHAR(M) | 255 | M 字節 | 定長,右填充空格 | MD5、UUID、郵編、ISO 代碼 |
| VARCHAR(M) | 65,535 | L+1/2 字節 | 變長,1-2B 存長度 | 通用文本、姓名、地址 |
| TINYTEXT/BLOB | 255 | L+1 | 不指定長度 | 極短備註、縮略圖 |
| TEXT/BLOB | 64 KB | L+2 | — | 文章、日誌、中等圖片 |
| MEDIUMTEXT/BLOB | 16 MB | L+3 | — | 長文檔、大圖片 |
| LONGTEXT/BLOB | 4 GB | L+4 | — | 超大對象、視頻切片 |
| ENUM('v1','v2',...) | 65,535 成員 | 1-2B | 單選,內部存數字 | 狀態機、類別、性別 |
| SET('v1','v2',...) | 64 成員 | 1-8B | 多選,位圖存儲 | 標籤、權限掩碼 |
關鍵差異:
- BLOB 二進制比較、TEXT 字符集比較
- VARCHAR 受行大小限制(65,535 字節共享),超長改 TEXT
- ENUM/SET 成員變更需 ALTER TABLE,慎用於高頻變更場景
日期時間列類型詳細表
| 類型 | 格式 | 範圍 | 存儲 | 特殊行為 |
| DATE | YYYY-MM-DD | 1000-01-01 ~ 9999-12-31 | 3B | — |
| TIME | HH:MM:SS[.fsp] | -838:59:59 ~ 838:59:59 | 3B+ | 可存時長、負值 |
| DATETIME | YYYY-MM-DD HH:MM:SS[.fsp] | 1000-01-01 ~ 9999-12-31 | 5-8B | 5.6.4+ 支持微秒 |
| TIMESTAMP | YYYY-MM-DD HH:MM:SS[.fsp] | 1970-01-01 UTC ~ 2038-01-19 UTC | 4-7B | **時區感知**,寫入自動轉 UTC,讀取轉會話時區 |
| YEAR | YYYY | 1901 ~ 2155 | 1B | 1 字節極省空間 |
選型建議:
- 需時區自動轉換(多地域應用)→ TIMESTAMP
- 歷史/未來日期、生日、審計時間 → DATETIME
- 僅需日期/時間 → DATE/TIME 省空間
- 5.6.4+ 指定 DATETIME(3) 存毫秒,TIMESTAMP(3) 存微秒
列屬性與約束
| 屬性 | 適用類型 | 作用 |
| UNSIGNED | 整數/浮點 | 禁用負值,正向範圍翻倍 |
| ZEROFILL | 數值 | 左補 0 至顯示寬度,隱含 UNSIGNED |
| BINARY | CHAR/VARCHAR/TEXT | 二進制比較,區分大小寫,加速索引 |
| NULL / NOT NULL | 所有 | 是否允許 NULL,NOT NULL 利於優化器 |
| DEFAULT value | 除 BLOB/TEXT | 隱式插入默認值,CURRENT_TIMESTAMP 支持時間類型 |
| AUTO_INCREMENT | 整數 | 自增主鍵,每表僅一列 |
| COMMENT 'str' | 所有 | 列註釋,SHOW FULL COLUMNS 可見 |
實戰建表範例
CREATE TABLE `student` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '姓名',
`chinese` TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '語文',
`maths` TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '數學',
`english` TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '英語',
`birthday` DATE NOT NULL COMMENT '出生日期',
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
PRIMARY KEY (`id`),
KEY `idx_birthday` (`birthday`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='學生成績表';
避坑清單
VARCHAR(255) 濫用 → 實際長度評估後定義
FLOAT/DOUBLE 存金額 → **必用 DECIMAL(19,4)**
TIMESTAMP 2038 年問題 → 長期項目改 DATETIME
ENUM 成員頻繁變更 → 改 VARCHAR + 字典表
- 缺失
NOT NULL + DEFAULT → 導致 NULL 汙染、統計失真
- 字符集不統一 → 全鏈路
utf8mb4,避免隱式轉換