【MySQL】MySQL学习的一大重点:MySQL数据类型(最全 + 面试八股版)
MySQL数据类型是建表、性能优化、索引设计、存储空间评估的基础,几乎每场MySQL面试都会被问到。掌握这一篇,能让你在表结构设计时少走90%的弯路。
1. MySQL数据类型总览(分类记忆法)
MySQL数据类型主要分为 5 大类:
| 大类 | 具体类型 | 常见使用场景 | 占用字节(常见) |
|---|---|---|---|
| 数值类型 | 整数:TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT 小数:FLOAT, DOUBLE, DECIMAL | ID、主键、数量、金额 | 1~8 字节 |
| 日期/时间 | DATE, DATETIME, TIMESTAMP, TIME, YEAR | 创建时间、更新时间、有效期 | 3~8 字节 |
| 字符串 | CHAR, VARCHAR, TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT BINARY, VARBINARY, BLOB系列 | 姓名、标题、文章、图片 | 变长 ~ 4GB |
| 枚举/集合 | ENUM, SET | 状态、标签、多选 | 1~8 字节 |
| JSON | JSON(MySQL 5.7+) | 配置、日志、半结构化数据 | 变长 |
2. 整数类型(最常用!)
| 类型 | 字节 | 有符号范围(Signed) | 无符号范围(Unsigned) | 推荐场景 |
|---|---|---|---|---|
| TINYINT | 1 | -128 ~ 127 | 0 ~ 255 | 状态、性别、是否删除 |
| SMALLINT | 2 | -32768 ~ 32767 | 0 ~ 65535 | 小ID、城市编码 |
| MEDIUMINT | 3 | -8388608 ~ 8388607 | 0 ~ 16777215 | 中等ID |
| INT | 4 | -21亿 ~ 21亿 | 0 ~ 42亿 | 最常用 主键、自增ID |
| BIGINT | 8 | -922亿亿 ~ 922亿亿 | 0 ~ 184亿亿 | 大ID、订单号、时间戳 |
重要建议:
- 主键、自增ID 强烈推荐 BIGINT UNSIGNED(最大可达 18446744073709551615)。
- 业务ID如果未来可能超过42亿,一定用BIGINT。
- 加
UNSIGNED可扩大一倍范围,且不会存负数(推荐)。
3. 小数 / 精确数值类型
| 类型 | 字节 | 精度特点 | 推荐场景 | 说明 |
|---|---|---|---|---|
| FLOAT | 4 | 单精度,约7位有效数字 | 科学计算、不要求精确 | 有精度丢失风险 |
| DOUBLE | 8 | 双精度,约15位有效数字 | 一般浮点计算 | 仍有精度丢失 |
| DECIMAL | M+2 | 精确小数(依赖参数) | 金额、利率、数量 | 强烈推荐,不会丢失精度 |
用法:
price DECIMAL(10,2) -- 总共10位,小数点后2位,最大 99999999.99
money DECIMAL(15,4) -- 适合高精度金额
4. 日期时间类型(重点区分!)
| 类型 | 字节 | 格式 | 范围 | 是否带时区 | 推荐用法 |
|---|---|---|---|---|---|
| DATE | 3 | YYYY-MM-DD | 1000-01-01 ~ 9999-12-31 | 否 | 仅日期(生日、发布日期) |
| TIME | 3 | HH:MM:SS | -838:59:59 ~ 838:59:59 | 否 | 仅时间 |
| DATETIME | 5 | YYYY-MM-DD HH:MM:SS | 1000-01-01 00:00:00 ~ 9999-12-31 | 否 | 最常用,记录创建/更新时间 |
| TIMESTAMP | 4 | YYYY-MM-DD HH:MM:SS | 1970-01-01 00:00:01 ~ 2038-01-19 | 是 | 系统时间、自动更新(推荐) |
| YEAR | 1 | YYYY | 1901 ~ 2155 | 否 | 年份 |
关键区别(面试高频):
DATETIME:存储实际日期时间,与时区无关,插入什么就是什么。TIMESTAMP:存储UTC时间戳,会根据当前时区自动转换,自动更新(ON UPDATE CURRENT_TIMESTAMP)。
最佳实践:
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时自动填充
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -- 更新时自动更新
-- 或者用 TIMESTAMP(更省空间)
5. 字符串类型(长度选择最容易踩坑)
| 类型 | 最大长度 | 存储方式 | 性能/空间 | 推荐场景 |
|---|---|---|---|---|
| CHAR(n) | 255字符 | 定长 | 速度快 | 固定长度,如性别、状态码、手机号区号 |
| VARCHAR(n) | 65535字节 | 变长 | 节省空间 | 绝大多数字符串(姓名、标题、地址) |
| TINYTEXT | 255字节 | 变长 | – | 短文本 |
| TEXT | 64KB | 变长 | – | 文章、描述 |
| MEDIUMTEXT | 16MB | 变长 | – | 长文章 |
| LONGTEXT | 4GB | 变长 | – | 超长文本、日志 |
CHAR vs VARCHAR 核心区别:
- CHAR:固定长度,存储时自动用空格补齐,检索时自动去空格 → 速度快,但浪费空间。
- VARCHAR:变长,实际长度 + 1~2字节前缀 → 节省空间,但稍慢。
选择建议:
- 长度 < 20 且固定 → 用 CHAR
- 大部分情况 → 用 VARCHAR
- 文字内容很长 → 用 TEXT系列(但TEXT不能加普通索引,只能加前缀索引)
6. 其他实用类型
- ENUM:枚举,节省空间(内部存整数)
status ENUM('pending','success','failed') NOT NULL
- SET:多选集合(类似位图)
- JSON(MySQL 5.7+):原生支持JSON,查询方便,但占用空间较大,不适合高频更新字段。
- BLOB系列:存二进制,如图片、文件(生产中更推荐存OSS,数据库只存路径)。
7. MySQL数据类型选择最佳实践(背诵版)
- 能用整数不用字符串(ID、状态、枚举全用整数)。
- 金额必须用 DECIMAL,绝不用 FLOAT/DOUBLE。
- 主键/自增ID 用 BIGINT UNSIGNED。
- 时间字段优先用 TIMESTAMP(自动更新 + 省空间)。
- 字符串优先 VARCHAR,只有固定短字符串才用 CHAR。
- 能用 TINYINT/SMALLINT 就不用 INT(省空间)。
- TEXT/BLOB 慎用,会影响表性能(尤其是大字段放主表)。
- 所有字段都尽量 NOT NULL,加默认值(减少NULL判断,优化索引)。
8. 经典面试题
- VARCHAR(255) 和 CHAR(255) 有什么区别?
- DATETIME 和 TIMESTAMP 的区别?哪个更好?
- 为什么不推荐用 FLOAT 存金额?
- 一个 INT 能存多大的数?超过怎么办?
- TEXT 类型字段能建索引吗?怎么建?
掌握以上内容,你就已经把 MySQL 数据类型这个“大重点”吃透了!
下一期我将继续讲 MySQL 表结构设计规范(20条最佳实践),包括字段命名、索引设计、拆表原则等。
想现在看具体某个类型的详细例子、建表语句合集,或直接进入“表设计规范”,随时告诉我!
继续加油,MySQL 基础打扎实,后面的索引、事务、锁、优化器才会水到渠成!