以下是 MySQL 中常见字段数据类型的分类总结表,包含关键特性和使用场景建议:
一、数值类型
类型 | 大小 | 有符号范围 | 无符号范围 | 场景 | 注意事项 |
---|---|---|---|---|---|
TINYINT | 1 Byte | -128 ~ 127 | 0 ~ 255 | 状态码、布尔值(0/1) | 替代 BOOLEAN (实际是TINYINT别名) |
SMALLINT | 2 Bytes | -32768 ~ 32767 | 0 ~ 65535 | 小范围计数(如城市ID) | |
MEDIUMINT | 3 Bytes | -8388608 ~ 8388607 | 0 ~ 16777215 | 中等范围ID | |
INT | 4 Bytes | -2147483648 ~ 2147483647 | 0 ~ 4294967295 | 主键ID、计数器 | 最常用整数类型 |
BIGINT | 8 Bytes | -2⁶³ ~ 2⁶³-1 | 0 ~ 2⁶⁴-1 | 分布式ID、大数据计数 | 可存雪花算法ID |
FLOAT | 4 Bytes | 约 ±3.4E+38(7位精度) | - | 科学计算 | 精度损失敏感场景避免使用 |
DOUBLE | 8 Bytes | 约 ±1.8E+308(15位精度) | - | 普通浮点数计算 | |
DECIMAL(M,D) | 变长(M+2) | 依赖 M(总位数)和 D(小数位) | - | 精确计算(如金额) | DECIMAL(10,2) = 总10位,小数2位 |
二、字符串类型
类型 | 最大长度 | 特点 | 场景 | 存储机制 |
---|---|---|---|---|
CHAR(N) | 255 字符 | 定长,尾部空格移除 | 固定长度(如MD5/UUID) | 始终分配 N 字符空间 |
VARCHAR(N) | 65535 字节(实际受行大小限制) | 变长,存实际长度 | 变长文本(用户名/地址) | 长度+1/2字节 + 数据 |
TINYTEXT | 255 字节 | 短文本 | 备注、简介 | 长度+1字节 + 数据 |
TEXT | 64 KB | 中等文本 | 文章内容、评论 | 长度+2字节 + 数据 |
MEDIUMTEXT | 16 MB | 长文本 | 富文本、JSON数据 | 长度+3字节 + 数据 |
LONGTEXT | 4 GB | 超大文本 | 小说、日志文件 | 长度+4字节 + 数据 |
BINARY(N) | 255 字节 | 定长二进制 | 加密Token | 类似 CHAR ,存二进制 |
VARBINARY(N) | 65535 字节 | 变长二进制 | 加密后的密码 | 类似 VARCHAR |
📌 字符集影响:
UTF8MB4(推荐)下,1字符占 4字节,VARCHAR(255)
最大实际存储约 63K 字符(受行大小65,535字节限制)
三、日期与时间类型
类型 | 格式 | 范围 | 场景 | 是否支持时区 |
---|---|---|---|---|
DATE | YYYY-MM-DD | 1000-01-01 ~ 9999-12-31 | 生日、过期日 | ❌ |
TIME | HH:MM:SS[.微秒] | -838:59:59 ~ 838:59:59 | 持续时间 | ❌ |
DATETIME | YYYY-MM-DD HH:MM:SS | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | 通用日期时间 | ❌(按存入值存储) |
TIMESTAMP | YYYY-MM-DD HH:MM:SS | 1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC | 自动更新的时间戳 | ✅(转UTC存储,按会话时区返回) |
YEAR | YYYY | 1901 ~ 2155 | 年份记录 | ❌ |
⚠️ TIMESTAMP陷阱:
- 2038年问题(范围限制)
- 时区转换可能造成显示差异(建议后端统一用 UTC 时间)
四、特殊类型
类型 | 存储方式 | 场景 | 示例 |
---|---|---|---|
ENUM | 1~2 Bytes(索引值) | 固定选项值(如状态) | ENUM('active','inactive','deleted') |
SET | 1~8 Bytes(位掩码) | 多选项组合(如权限) | SET('read','write','execute') |
JSON | LONGTEXT 格式 | 半结构化数据(MySQL 5.7+) | {"name": "Alice", "age": 25} |
BOOLEAN | TINYINT(1) 别名 | 真/假值 | true 存为 1 ,false 存为 0 |
五、选择建议与优化
-
整数类型
- 优先选 UNSIGNED(非负数场景)
- 主键用 BIGINT UNSIGNED(适应未来扩展)
-
字符串类型
- 固定长度用 CHAR(如
CHAR(36)
存 UUID) - 变长文本用 VARCHAR,但避免过长(超 16383 字符用 TEXT)
- 字符集统一为
utf8mb4
(支持 Emoji 和生僻字)
- 固定长度用 CHAR(如
-
时间类型
- 通用时间用 DATETIME
- 需要自动更新或时区转换用 TIMESTAMP
- 存储 UTC 时间(应用层处理时区转换)
-
精确计算
- 金额必须用 DECIMAL,禁止用 FLOAT/DOUBLE
- 示例:
DECIMAL(15,2)
(最大 999,999,999,999.99)
-
JSON 类型优势
-- 直接查询JSON字段 SELECT * FROM users WHERE JSON_EXTRACT(profile, '$.age') > 30;
- 支持部分更新(MySQL 8.0+)
- 索引:
JSON
字段可建虚拟列索引
六、避坑指南
- ENUM/SET 慎用:修改选项需重建表,用关联表或 CHECK 约束替代
- BLOB/TEXT 分离:大字段单独存表,避免拖慢主表查询
- 禁止
VARCHAR(65535)
:实际最大约 16383 字符(utf8mb4) - TIMESTAMP 时区:确保数据库和应用的时区配置一致
💡 终极原则:
用最小合适类型 → 节省空间 + 提升索引效率
避免 NULL → 用默认值(如''
或0
)减少索引复杂度
根据业务场景选择合适类型,可显著提升性能和存储效率!