MySQL 数据类型与 Java 类型的完整映射手册,涵盖整数、浮点、字符串、日期、二进制等所有类型,以及 MyBatis 特殊映射和常见踩坑点。
MySQL 系列:MySQL 简介 · MySQL 数据库设计规范 · MySQL 索引原理与优化
整数类型
| MySQL 类型 | 字节 | 有符号范围 | 无符号范围 | Java 类型 | 备注 |
|---|---|---|---|---|---|
TINYINT |
1 | -128 ~ 127 | 0 ~ 255 | Byte / Integer |
通常用 Integer,避免拆箱坑 |
SMALLINT |
2 | -32,768 ~ 32,767 | 0 ~ 65,535 | Short / Integer |
很少单独使用 |
MEDIUMINT |
3 | -8,388,608 ~ 8,388,607 | 0 ~ 16,777,215 | Integer |
|
INT |
4 | -2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 | Integer |
普通 ID、状态码首选 |
BIGINT |
8 | -9.2×10¹⁸ ~ 9.2×10¹⁸ | 0 ~ 1.8×10¹⁹ | Long |
分布式 ID、时间戳必用 |
[!tip] 选型原则
- 主键 ID →
BIGINT UNSIGNED+ JavaLong- 业务状态/枚举 →
TINYINT+ JavaInteger(MyBatis 可映射枚举)- 计数器/普通数字 →
INT+ JavaInteger- 避免用
TINYINT(1)存布尔,会被 JDBC 驱动自动映射为Boolean,建议显式加tinyint1isBit=false
浮点 / 定点类型
| MySQL 类型 | 字节 | 精度 | Java 类型 | 备注 |
|---|---|---|---|---|
FLOAT |
4 | ~7 位有效数字 | Float |
不精确,慎用于金额 |
DOUBLE |
8 | ~15 位有效数字 | Double |
不精确,慎用于金额 |
DECIMAL(M,D) |
变长 | 精确 | BigDecimal |
金额/价格必用 |
[!warning] 金额存储铁律 金额字段必须使用
DECIMAL(19,4)+ JavaBigDecimal,禁止使用 FLOAT/DOUBLEprice DECIMAL(19, 4) NOT NULL DEFAULT '0.0000' COMMENT '价格'private BigDecimal price;
字符串类型
| MySQL 类型 | 最大长度 | 存储方式 | Java 类型 | 备注 |
|---|---|---|---|---|
CHAR(N) |
255 字符 | 定长,不足补空格 | String |
定长编码(MD5、UUID 去横线) |
VARCHAR(N) |
65,535 字节 | 变长,1-2 字节前缀 | String |
通用文本字段 |
TINYTEXT |
255 字节 | 变长 | String |
很少用 |
TEXT |
65,535 字节 | 变长 | String |
短文本内容 |
MEDIUMTEXT |
16MB | 变长 | String |
JSON 配置、长文本 |
LONGTEXT |
4GB | 变长 | String |
日志、超长内容(慎用) |
JSON |
同 LONGTEXT | 二进制优化 | String |
MySQL 5.7.8+ |
[!tip] VARCHAR 选型原则
- 短标识符(名称、编码)→
VARCHAR(64)或VARCHAR(128)- 业务描述 →
VARCHAR(512)- URL / 路径 →
VARCHAR(2048)- 超过 2048 考虑用
TEXTVARCHAR(N)的 N 是字符数,不是字节数(utf8mb4 每字符最多 4 字节)
日期 / 时间类型
| MySQL 类型 | 字节 | 范围 | Java 类型 | 备注 |
|---|---|---|---|---|
DATE |
3 | 1000-01-01 ~ 9999-12-31 | LocalDate |
仅日期 |
TIME |
3 | -838:59:59 ~ 838:59:59 | LocalTime |
仅时间 |
DATETIME |
8 | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | LocalDateTime |
不含时区 |
TIMESTAMP |
4 | 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07 | LocalDateTime / Date |
含时区转换,2038 问题 |
YEAR |
1 | 1901 ~ 2155 | Integer |
极少用 |
[!warning] TIMESTAMP vs DATETIME
TIMESTAMP会随时区变化,存储 UTC,取出自动转本地时区DATETIME存什么取什么,无时区概念- 推荐使用
DATETIME+ JavaLocalDateTime,避免时区问题- 创建时间/更新时间 →
DATETIME DEFAULT CURRENT_TIMESTAMP
二进制类型
| MySQL 类型 | 最大长度 | Java 类型 | 备注 |
|---|---|---|---|
BINARY(N) |
255 字节 | byte[] |
定长二进制 |
VARBINARY(N) |
65,535 字节 | byte[] |
变长二进制 |
BLOB |
65,535 字节 | byte[] |
二进制对象 |
MEDIUMBLOB |
16MB | byte[] |
|
LONGBLOB |
4GB | byte[] |
[!caution] 二进制存储建议 文件/图片等大二进制数据不建议存 MySQL,应使用对象存储(S3Plus/OSS),MySQL 只存 URL。
布尔 / 枚举 / 集合
| MySQL 类型 | 说明 | Java 类型 | 备注 |
|---|---|---|---|
BOOLEAN / BOOL |
等同 TINYINT(1) |
Boolean / Integer |
注意 JDBC 驱动映射 |
ENUM('a','b') |
枚举字符串 | String / 自定义 Enum |
修改枚举值需 DDL,谨慎 |
SET(...) |
集合 | String |
很少用 |
完整 Java ↔ MySQL 类型对应速查
Java Type → MySQL Type
─────────────────────────────────────────
Boolean → TINYINT(1)
Byte → TINYINT
Short → SMALLINT
Integer → INT
Long → BIGINT
Float → FLOAT
Double → DOUBLE
BigDecimal → DECIMAL(M,D)
String → VARCHAR(N) / TEXT / CHAR(N)
byte[] → BLOB / VARBINARY
java.util.Date → DATETIME / TIMESTAMP
java.sql.Date → DATE
java.sql.Timestamp → TIMESTAMP
LocalDate → DATE
LocalTime → TIME
LocalDateTime → DATETIME
Enum → VARCHAR / TINYINT(存 ordinal 或 name)
MyBatis / MBG 特殊映射
| 场景 | MySQL | Java | MyBatis 配置 |
|---|---|---|---|
| 枚举字段 | TINYINT |
SomeEnum |
typeHandler=EnumOrdinalTypeHandler |
| JSON 字段 | JSON / TEXT |
自定义 BO | 自定义 TypeHandler |
| 乐观锁版本 | BIGINT |
Long |
配合 @Version 或手动 CAS |
| 软删除状态 | TINYINT |
StatusEnum |
枚举 TypeHandler |
| 分布式 ID | BIGINT UNSIGNED |
Long |
注意无符号溢出,Java Long 最大值够用 |
常用建表规范
CREATE TABLE `t_example` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`entity_key` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '业务唯一键',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态 1-有效 0-无效',
`amount` DECIMAL(19,4)NOT NULL DEFAULT '0.0000' COMMENT '金额',
`ext_info` VARCHAR(2048) DEFAULT NULL COMMENT '扩展JSON',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_entity_key` (`entity_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='示例表';
常见坑点速记
[!bug] 高频踩坑
TINYINT(1)被驱动当 Boolean:在 JDBC URL 加tinyint1isBit=falseTIMESTAMP2038 问题:新表统一用DATETIMEVARCHAR长度是字符数:VARCHAR(255)在 utf8mb4 下最大 1020 字节INT(11)括号无意义:括号只影响展示宽度,不影响存储范围(MySQL 8.0.17 已废弃)- 枚举用 ordinal 存储:Java 枚举顺序变化会导致数据错乱,建议用
name()或指定 code 字段DECIMAL精度:DECIMAL(19,4)最多 15 位整数 + 4 位小数- 分布式 ID 用 BIGINT:
INT上限约 21 亿,高并发系统容易溢出
评论 (0)
发表评论