【MySQL 笔记】数据类型详解(2026 年生产视角)
MySQL 的数据类型选择直接影响存储空间、查询性能、索引效率和数据正确性。
选错了类型,后期改成本非常高(尤其是大表)。
一、MySQL 8.0+ 最常用数据类型对比表(推荐记忆版)
| 分类 | 类型 | 存储大小 | 实际取值范围 | 是否有符号 | 推荐场景(2026主流) | 常见误用坑 |
|---|---|---|---|---|---|---|
| 整数 | TINYINT | 1 字节 | -128 ~ 127 / 0 ~ 255 | 有/无 | 状态码、性别、枚举(0/1/2) | 别存年龄(>127会溢出) |
| SMALLINT | 2 字节 | -32768 ~ 32767 / 0 ~ 65535 | 有/无 | 标签数量、城市编码 | — | |
| MEDIUMINT | 3 字节 | -8388608 ~ 8388607 | 有/无 | 极少用(节省空间时) | 基本被 INT 取代 | |
| INT / INTEGER | 4 字节 | -21亿 ~ 21亿 / 0 ~ 42亿 | 有/无 | 用户ID、订单ID(无符号)、点赞数 | 别用在未来可能超 42 亿的场景 | |
| BIGINT | 8 字节 | -9e18 ~ 9e18 / 0 ~ 1.8e19 | 有/无 | 主键、雪花ID、支付金额(分)、时间戳 | 最安全的选择(现代项目主力) | |
| 小数 | DECIMAL(M,D) / NUMERIC | 按精度计算 | 精确小数(M总位数,D小数位) | 有 | 金额、汇率、积分(必须用) | 别用 FLOAT/DOUBLE 存钱! |
| FLOAT | 4 字节 | ≈ ±3.4E±38(7位有效数字) | 有 | 科学计算、统计近似值 | 精度丢失严重 | |
| DOUBLE | 8 字节 | ≈ ±1.79E±308(15~16位有效数字) | 有 | 高精度科学计算 | 金融场景禁用 | |
| 字符串 | CHAR(n) | n 字节(固定) | 0~255 字符 | — | 固定长度(如性别 M/F、省份代码) | 浪费空间(短字符串也占满) |
| VARCHAR(n) | 实际长度+1~2字节 | 0~65535 字节(utf8mb4 下≈16383字符) | — | 用户名、昵称、标题、地址(最常用) | n 设太大浪费索引空间 | |
| TINYTEXT | 最大 255 字节 | — | — | 极短文本 | 基本不用 | |
| TEXT | 最大 64KB | — | — | 文章正文、评论、富文本 | 索引限制(只能前缀) | |
| MEDIUMTEXT | 最大 16MB | — | — | 长文章、日志 | — | |
| LONGTEXT | 最大 4GB | — | — | 超长内容(很少用) | 慎用,性能差 | |
| 日期时间 | DATE | 3 字节 | 1000-01-01 ~ 9999-12-31 | — | 生日、注册日期 | — |
| DATETIME | 5~8 字节 | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | — | 创建时间、订单时间(最常用) | 带时区需求用 TIMESTAMP | |
| TIMESTAMP | 4 字节 | 1970-01-01 ~ 2038-01-19 | — | 自动更新时间(2038问题) | 2038 年问题(已基本被 DATETIME 取代) | |
| TIME | 3 字节 | -838:59:59 ~ 838:59:59 | — | 时长、营业时间 | — | |
| YEAR | 1 字节 | 1901 ~ 2155 | — | 年份(极少用) | — | |
| JSON | JSON | 按内容 | 最大 1GB | — | 配置、扩展字段、复杂结构(现代主力) | 大 JSON 慎用(查询性能) |
| 其他 | ENUM(‘男’,’女’,’保密’) | 1~2 字节 | 枚举值 | — | 性别、状态(小范围固定值) | 扩展困难(加值要改表) |
| SET | 1~8 字节 | 多选枚举 | — | 标签(少量固定) | 基本被 JSON 取代 | |
| BIT(n) | n/8 字节 | 位字段 | — | 权限位图(极少用) | 可读性差 |
二、2026 年生产环境推荐组合(强烈建议)
| 场景 | 推荐类型组合 | 为什么 |
|---|---|---|
| 主键 / 关联ID | BIGINT UNSIGNED AUTO_INCREMENT | 安全、足够大、索引友好 |
| 用户名/昵称/标题 | VARCHAR(64) ~ VARCHAR(255) | utf8mb4 下够用,索引前缀够长 |
| 手机号 | VARCHAR(20) 或 CHAR(11) | 考虑 +86 等前缀,VARCHAR 更灵活 |
| 金额 / 单价 | DECIMAL(12,2) 或 DECIMAL(18,4) | 精确、无误差 |
| 创建/更新时间 | DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3) | 毫秒级、自动维护、跨时区友好 |
| 状态码 | TINYINT UNSIGNED | 0~255 足够,索引小 |
| 性别/审核状态 | TINYINT(1) 或 ENUM | TINYINT 更灵活(后期加状态容易) |
| 评论/文章正文 | TEXT 或 MEDIUMTEXT | 根据长度选 |
| 扩展字段 | JSON | 灵活、无需频繁改表 |
三、常见致命误用 & 血泪教训
- 用 INT 做用户ID → 公司用户破 42 亿时崩溃
- 用 FLOAT/DOUBLE 存金额 → 0.1 + 0.2 ≠ 0.3
- 用 VARCHAR(500) 存用户名 → 索引占用巨大,查询变慢
- 用 TIMESTAMP 存未来时间 → 2038 年问题(虽已少见,但仍需警惕)
- 所有字段都允许 NULL → 逻辑混乱 + 索引效率下降
- 用 CHAR 存变长内容 → 空间浪费严重
- 枚举用 ENUM 存动态状态 → 后期加值要 ALTER TABLE
四、快速记忆口诀(生产选型三原则)
- 能用小的绝不用大的(TINYINT > SMALLINT > INT > BIGINT)
- 能精确就别用浮点(金额、比率必须 DECIMAL)
- 时间优先 DATETIME(3)(除非明确要自动更新且不关心 2038)
- 字符串优先 VARCHAR(CHAR 只在固定长度极短时用)
- 现代项目 JSON 救急(但别滥用)
下一期预告建议:MySQL 索引全家桶(上)—— 索引类型 + 聚簇 vs 非聚簇 + 最左前缀原则
有哪个数据类型在你的项目里选型争议最大,或者踩过最坑的类型,欢迎留言讨论~
祝大家字段类型选得又省又稳!📏