合理選擇數據類型與約束,是數據庫設計性能與數據質量的基石。本文系統梳理MySQL支持的數據類型、字段屬性約束及建表最佳實踐。
| 類型 | 存儲範圍(有符號) | 存儲範圍(無符號) | 字節 | 適用場景 |
|---|---|---|---|---|
| TINYINT | -128 ~ 127 | 0 ~ 255 | 1 | 年齡、狀態碼、布爾值 |
| SMALLINT | -32768 ~ 32767 | 0 ~ 65535 | 2 | 小範圍計數 |
| MEDIUMINT | -8388608 ~ 8388607 | 0 ~ 16777215 | 3 | 中等計數 |
| INT/INTEGER | -2147483648 ~ 2147483647 | 0 ~ 4294967295 | 4 | 通用ID、計數器 |
| BIGINT | -2^63 ~ 2^63-1 | 0 ~ 2^64-1 | 8 | 大數據量ID、時間戳 |
| FLOAT(M,D) | 單精度浮點數 | - | 4 | 科學計算、非精確值 |
| DOUBLE(M,D) | 雙精度浮點數 | - | 8 | 高精度科學計算 |
| DECIMAL(M,D) | 精確定點數 | - | M+2 | 貨幣、金融、精確計算首選 |
關鍵點:
M為顯示寬度,D為小數位數。FLOAT(3,1)範圍-99.9~99.9UNSIGNED擴大正數範圍;浮點/定點數不可用DECIMAL必須指定M,D;FLOAT/DOUBLE可選TINYINT(3))| 類型 | 最大長度 | 存儲特點 | 適用場景 |
|---|---|---|---|
| CHAR(M) | 255字符 | 固定長度,右補空格 | 定長代碼(如MD5、UUID、郵編) |
| VARCHAR(M) | 65,535字節 | 實際長度+1/2字節長度前綴 | 變長文本(姓名、標題、郵箱) |
| TINYTEXT | 255字節 | 不指定長度 | 極短文本 |
| TEXT | 64KB | - | 較長文本 |
| MEDIUMTEXT | 16MB | - | 長文本 |
| LONGTEXT | 4GB | - | 超長文本 |
| BLOB系列 | 對應TEXT | 二進制存儲 | 圖片、文件、序列化對象 |
關鍵點:
CHAR按定長存儲,VARCHAR按實際長度+長度前綴存儲VARCHAR或NVARCHAR(Unicode),避免TEXT類型(讀取效率低、難建索引)VARCHAR(MAX)替代TEXT| 類型 | 範圍 | 字節 | 格式 | 備註 |
|---|---|---|---|---|
| DATE | 1000-01-01 ~ 9999-12-31 | 3 | YYYY-MM-DD | 純日期 |
| TIME | -838:59:59 ~ 838:59:59 | 3 | HH:MM:SS | 純時間 |
| DATETIME | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | 8 | YYYY-MM-DD HH:MM:SS | 日期時間,無時區 |
| TIMESTAMP | 1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC | 4 | YYYY-MM-DD HH:MM:SS | 帶時區自動轉換,受2038年問題限制 |
| YEAR | 1901 ~ 2155 | 1 | YYYY | 年份 |
實踐建議:PHP常用INT存儲Unix時間戳,應用層格式化;MySQL 5.6.4+ DATETIME支持微秒且無2038年問題,優先選擇。
PRIMARY KEY (column_name)
FOREIGN KEY (uid) REFERENCES user(uid)
uid MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT
NULL/0觸發自增username CHAR(20) NOT NULL DEFAULT ''
regdate INT(10) UNSIGNED NOT NULL DEFAULT 0
NOT NULL防止意外空值,配合DEFAULT簡化插入語句ALTER TABLE user CHANGE username username CHAR(20) NULL(去掉非空)UNIQUE KEY username (username)
-- 添加/刪除
ALTER TABLE tb_name ADD UNIQUE (column_name);
ALTER TABLE tb_name DROP INDEX column_name;
NULL值(標準SQL規範)KEY email (email)
-- 等同於
INDEX email (email)
WHERE、JOIN、ORDER BY的列建立索引CREATE TABLE `user` (
`uid` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
`username` CHAR(15) NOT NULL DEFAULT '',
`password` CHAR(32) NOT NULL DEFAULT '',
`email` VARCHAR(40) NOT NULL DEFAULT '',
`regdate` INT(10) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`uid`),
UNIQUE KEY `username` (`username`),
KEY `email` (`email`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
表選項說明:
ENGINE=MyISAM:高性能、無事務、全文索引;InnoDB:事務、行鎖、外鍵CHARSET=utf8:國際通用編碼,避免亂碼AUTO_INCREMENT=1:自增起始值| 業務場景 | 推薦類型 | 約束建議 |
|---|---|---|
| 用戶ID | BIGINT UNSIGNED | PK + AUTO_INCREMENT |
| 手機號 | CHAR(11) | UNIQUE + NOT NULL |
| 郵箱 | VARCHAR(100) | UNIQUE + INDEX |
| 密碼哈希 | CHAR(60) (bcrypt) | NOT NULL |
| 金額/價格 | DECIMAL(10,2) | NOT NULL + DEFAULT 0.00 |
| 狀態枚舉 | TINYINT UNSIGNED | NOT NULL + DEFAULT 1 + CHECK |
| 創建時間 | DATETIME / TIMESTAMP | NOT NULL + DEFAULT CURRENT_TIMESTAMP |
| 長文本/文章 | LONGTEXT / VARCHAR(MAX) | - |
| 圖片/二進制 | LONGBLOB / 存儲路徑 | 建議存路徑,文件存對象存儲 |
遵循「最小足夠原則」選擇類型,配合完整約束體系,構建高性能、高可靠的數據庫基礎架構。