【MySQL】学习的一大重点:MySQL 数据类型 完整详解(2026 最新版)
MySQL 数据类型是数据库设计、性能优化、存储空间控制的核心基础。选错数据类型,可能导致存储浪费、查询变慢、索引失效等问题。本文系统梳理 MySQL 8.0 / 8.4 中所有常用数据类型,并给出生产环境最佳实践建议。
1. MySQL 数据类型总览分类
| 分类 | 数据类型 | 存储空间 | 推荐使用场景 |
|---|---|---|---|
| 整数 | TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT | 1~8 字节 | ID、数量、状态等 |
| 浮点数 | FLOAT, DOUBLE, DECIMAL | 4/8/可变字节 | 金额(必须用 DECIMAL)、科学计算 |
| 日期时间 | DATE, DATETIME, TIMESTAMP, TIME, YEAR | 3~8 字节 | 时间相关字段 |
| 字符串 | CHAR, VARCHAR, TEXT, BLOB, ENUM, SET | 可变 | 姓名、标题、内容等 |
| JSON | JSON | 可变 | 结构化文档、配置、扩展字段 |
| 空间 | GEOMETRY 等 | 可变 | GIS 系统 |
| 其他 | BIT | 1~8 字节 | 位运算场景 |
2. 整数类型(最常用)
| 类型 | 字节 | 有符号范围 | 无符号范围 (UNSIGNED) | 推荐场景 |
|---|---|---|---|---|
| TINYINT | 1 | -128 ~ 127 | 0 ~ 255 | 状态、性别、是否删除 |
| SMALLINT | 2 | -32768 ~ 32767 | 0 ~ 65535 | 城市编码、小数量 |
| MEDIUMINT | 3 | -8388608 ~ 8388607 | 0 ~ 16777215 | 一般够用 |
| INT | 4 | -21亿 ~ 21亿 | 0 ~ 42亿 | 最常用(用户ID、订单ID) |
| BIGINT | 8 | -922亿亿 ~ 922亿亿 | 0 ~ 184亿亿 | 主键自增、大业务量场景 |
最佳实践:
- 普通业务主键、计数等 → INT UNSIGNED(节省 1 字节)
- 超大业务量(抖音级)→ BIGINT UNSIGNED
- 状态字段 → TINYINT UNSIGNED(0-255 足够)
3. 浮点数与精确数值类型(非常重要!)
- FLOAT(4 字节):单精度,约 7 位有效数字 → 不推荐存金额
- DOUBLE(8 字节):双精度,约 15 位有效数字 → 科学计算可接受
- DECIMAL(M,D):精确小数,M 是总位数,D 是小数位数
金额字段强烈推荐:
price DECIMAL(10,2) -- 最大 99999999.99
amount DECIMAL(16,4) -- 高精度金额
错误示范:
price FLOAT -- 可能出现 19.999999999 的精度问题
4. 日期时间类型(必须掌握区别)
| 类型 | 字节 | 格式 | 是否带时区 | 推荐场景 |
|---|---|---|---|---|
| DATE | 3 | YYYY-MM-DD | 否 | 生日、日期 |
| TIME | 3 | HH:MM:SS | 否 | 时长 |
| DATETIME | 5 | YYYY-MM-DD HH:MM:SS | 否 | 最常用(创建时间、更新时间) |
| TIMESTAMP | 4 | YYYY-MM-DD HH:MM:SS | 是 | 需要时区转换、自动更新 |
| YEAR | 1 | YYYY | 否 | 年份 |
最佳实践:
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
TIMESTAMP vs DATETIME:
- TIMESTAMP 受时区影响,适合全球业务
- DATETIME 不受时区影响,推荐大多数国内业务使用
5. 字符串类型(重中之重)
| 类型 | 最大长度 | 存储方式 | 推荐场景 |
|---|---|---|---|
| CHAR(n) | 255 字符 | 定长 | 固定长度(如性别、状态码) |
| VARCHAR(n) | 65535 字符 | 变长 | 最常用(姓名、标题、地址) |
| TINYTEXT | 255 字符 | 变长 | 短文本 |
| TEXT | 65535 字符 | 变长 | 文章内容、备注 |
| MEDIUMTEXT | 16MB | 变长 | 长文章 |
| LONGTEXT | 4GB | 变长 | 极长内容 |
| ENUM | 65535 个成员 | 1~2 字节 | 状态枚举(如 order_status) |
| SET | 64 个成员 | 1~8 字节 | 多选(如用户权限) |
生产建议:
- 姓名、标题、手机号 → VARCHAR(50~100)
- 地址 → VARCHAR(255)
- 文章内容 → MEDIUMTEXT 或 LONGTEXT
- 状态字段 → ENUM 或 TINYINT(ENUM 可读性更好)
6. JSON 类型(MySQL 5.7+ 强烈推荐)
ALTER TABLE user ADD COLUMN extra JSON;
-- 存储对象
INSERT INTO user (extra) VALUES ('{"nickname":"张三","tags":["vip","active"]}');
-- 查询
SELECT extra->>'$.nickname' AS nickname
FROM user
WHERE extra->'$.tags' MEMBER OF ('["vip"]');
优点:
- 支持 JSON 索引(MySQL 8.0+)
- 结构灵活,适合扩展字段
- 比 VARCHAR 存 JSON 字符串性能更好
7. 数据类型选择最佳实践(生产 Checklist)
- 能用整数就不用字符串(手机号除外)
- 金额必须用 DECIMAL
- 能用 TINYINT / SMALLINT 就不用 INT
- 固定长度字符串用 CHAR,变长用 VARCHAR
- 创建时间、更新时间:
- 推荐:
created_at DATETIME DEFAULT CURRENT_TIMESTAMP updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
- 主键:推荐
BIGINT UNSIGNED AUTO_INCREMENT - 避免使用 FLOAT/DOUBLE 存精确数值
- 枚举类型优先考虑 ENUM 或 TINYINT + 注释
- 大文本优先 JSON(结构化)或 MEDIUMTEXT
- 所有字符类型必须指定字符集(推荐 utf8mb4)
推荐建表模板(现代写法):
CREATE TABLE `user` (
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(50) NOT NULL UNIQUE,
`nickname` VARCHAR(80) NULL,
`status` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1正常 0禁用',
`balance` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`extra` JSON NULL,
INDEX idx_status (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';
学习建议:
- 每设计一张表,都对照上面的表格检查数据类型是否合理
- 多使用
SHOW CREATE TABLE查看别人设计的表结构 - 关注字段的实际业务范围,不要盲目用最大类型
想继续深入吗?我可以立刻给你以下内容:
- MySQL 字符集与排序规则(utf8mb4)深度讲解
- 30 道数据类型选择面试题
- 高效建表规范模板(50+ 张常用表结构)
- 数据类型对索引和性能的影响
- MySQL 8.0+ 新增数据类型特性
回复「字符集」、「面试题」或「建表模板」,我马上发给你!
掌握了 MySQL 数据类型,你就真正迈入了数据库设计的大门!继续加油!🚀