主要内容
-
介绍mysql中常⽤的数据类型
-
mysql类型和java类型对应关系
-
数据类型选择的⼀些建议
MySQL的数据类型
主要包括以下五⼤类
• 整数类型:bit、bool、tinyint、smallint、mediumint、int、bigint
• 浮点数类型:float、double、decimal
• 字符串类型:char、varchar、tinyblob、blob、mediumblob、longblob、 tinytext、text、mediumtext、longtext
• ⽇期类型:Date、DateTime、TimeStamp、Time、Year
• 其他数据类型:暂不介绍,⽤的⽐较少。
整数类型
BOOL 不是独立类型,只是 TINYINT (1) 别名;BIT 属于位值类型,严格来说不属于整数,但经常放一起考MySQL
| 类型 | 存储 | 取值范围 | 说明 & 场景 |
|---|---|---|---|
| BIT(M) | M 位,M=1~64 | BIT (1) 只能存 0/1;BIT (M) 可存 0~2M−1 | 位类型。BIT(1)用来存位标记;查询返回二进制,程序里容易乱码。开发一般不推荐 |
| BOOL / BOOLEAN | 1 字节 | 0=false,非 0=true | 别名,建表后实际就是TINYINT(1)。可以插入 2、3 等,不止只能 0 和 1MySQL |
| TINYINT | 1 字节 | 有符号:-128 ~ 127无符号 UNSIGNED:0 ~ 255 | 状态码:0 启用,1 禁用,2 删除。最常用 |
| SMALLINT | 2 字节 | 有符号:-32768 ~ 32767无符号:0 ~ 65535 | 少量计数 |
| MEDIUMINT | 3 字节 | 有符号:-8388608 ~ 8388607无符号:0 ~ 16777215 | 实际项目很少用 |
| INT(INTEGER) | 4 字节 | 有符号:-2147483648 ~ 2147483647无符号:0 ~ 4294967295 | 普通 ID、数字;老项目主键常用 |
| BIGINT | 8 字节 | 有符号:-9223372036854775808 ~ 9223372036854775807无符号:0 ~ 18446744073709551615 | 现在推荐主键用 BIGINT,雪花 ID 必用 |
核心考点(面试 / 考试高频)
BOOL = TINYINT(1),只是别名,不是单独布尔类型,可以存除 0、1 以外的值
CREATE TABLE t(
flag BOOL
);
INSERT INTO t VALUES(0),(1),(2); -- 可以插入2!2不是true吗
SELECT * FROM t; -- 0是false,1、2都被当作tru
BIT(M):位类型,不是整数 。M 范围 1~64。BIT(1)写入b'1';select 查询出来是二进制字符串,客户端容易显示乱码。Java 里要特殊处理,开发尽量不用 BIT 存布尔,优先 TINYINT。UNSIGNED:无符号,去掉负数,上限变大。INT(5)这种括号里 M:显示宽度,不限制存储范围,MySQL8.0 ZEROFILL 废弃。
开发选型建议
- 布尔 / 状态:优先
TINYINT(不要 BIT),语义清晰,程序读取简单 - 主键 id:新项目优先
BIGINT,防止数据超过 INT 上限 - MEDIUMINT:尽量避开,3 字节,兼容性差,业务很少用到
一句话区分
- IT:位类型,存二进制,不推荐业务布尔
- BOOL:只是 TINYINT (1) 别名
- TINYINT/SMALLINT/MEDIUMINT/INT/BIGINT:真正整数,字节依次变大
浮点数类型
✅ 重点:FLOAT、DOUBLE 是浮点数(近似值) ;DECIMAL 是定点数(精确值),专门用来存金额。
| 类型 | 字节 | 语法 | 特点 | 适用场景 |
|---|---|---|---|---|
| FLOAT | 4 字节 | FLOAT(M,D) | 单精度,近似存储,有精度丢失;M 总位数,D 小数位 | 对精度要求不高的数值,如温度、权重 |
| DOUBLE | 8 字节 | DOUBLE(M,D) | 双精度,精度比 float 高,但仍然是近似值,也会丢精度 | 科学计算,非财务场景 |
| DECIMAL(p,s)也写作 NUMERIC | 可变 | DECIMAL (总位数 p, 小数位 s) | 定点,精确存储,不会丢失精度。p 最大 65,s 最大 30,s≤p | 金额、财务、计费,必选! |
核心考点
- FLOAT / DOUBLE 是二进制浮点数,存在精度误差
-- 示例,会出现意料之外结果
SELECT 0.1 + 0.2;
浮点数不能精确表示部分十进制小数,不能用来做金额!
不要用 FLOAT(10,2) 存钱!会出现 0.2999999999999999 这种情况。
DECIMAL 原理:按字符串形式保存数字 ,不是二进制。 DECIMAL(10,2):
- p=10:一共最多 10 位数字
- s=2:小数占 2 位 👉 整数部分最多 8 位,范围:
-99999999.99 ~ 99999999.99
- M/D(p/s)含义
- FLOAT (M,D):M 总有效数字,D 小数位数;只是显示限制,不是严格校验,超出会四舍五入。
- DECIMAL (p,s):p 是精度(全部数字个数),s 标度(小数位),超出范围会报错(严格模式)。
- 存储空间:DECIMAL 不是固定字节,每 9 位数字占 4 字节,剩下不足 9 位按情况分配。 例:DECIMAL (10,2),一共 10 位,整数 8,小数 2。
选型口诀(面试常考)
- 金额财务:DECIMAL,必须用定点,保证精确
- 不需要很高精度、数值大、追求速度:FLOAT
- 需要更高精度,但不需要绝对精确:DOUBLE
建表示例
CREATE TABLE test_num(
weight FLOAT(5,2),
rate DOUBLE(8,3),
money DECIMAL(12,2) -- 金额常用 DECIMAL(12,2)
);
高频坑
- 浮点数不要直接用
=做等值比较 :where a=0.1,很容易匹配不到,误差导致。 - DECIMAL 是精确,但运算速度比 float/double 慢,牺牲性能换精度。
- MySQL8 中,FLOAT (M,D)、DOUBLE (M,D) 这种写法已经不推荐,属于废弃语法;推荐直接写 FLOAT / DOUBLE,不加 (M,D)。
一句话总结: FLOAT、DOUBLE:近似,二进制存储,有精度丢失 DECIMAL:定点精确存储,财务金额首选
MySQL 字符串类型:CHAR、VARCHAR、TEXT
核心考点:CHAR 固定长度;VARCHAR 可变长度;TEXT 大文本
| 类型 | 存储特点 | 长度范围 | 占用空间 | 特点 & 场景 |
|---|---|---|---|---|
| CHAR(M) | 固定长度字符串 | M:0~255 | M 个字符,不管存多少,都占 M 字符空间 | 尾部空格会被删除。适合长度固定的值:手机号、身份证、编码。M 代表字符数,不是字节! |
| VARCHAR(M) | 可变长度字符串 | MySQL5.0+:M 0~65535(字符) | 实际字符数 + 1~2 字节长度前缀≤255 字符:前缀 1 字节>255 字符:前缀 2 字节 | 存多少占多少。常用:用户名、地址、简介。M 是最多字符数,不是字节 |
| TEXT | 大文本,属于 BLOB 系列里的字符型 | 最大 65535 字符(约 64KB) | 只存内容,不存默认值,不能有默认值 | 长文本、文章内容。不能指定 M,不能建普通索引(可前缀索引) |
补充 3 个 TEXT 系列(考试偶尔考)
- TINYTEXT:最大 255 字符
- MEDIUMTEXT:最大 16MB
- LONGTEXT:最大 4GB
重点考点
CHAR (M):固定长,尾部空格会被截断

CHAR 适合:长度几乎不变的数据,比如身份证 18 位。查询性能略好,不用读长度。
VARCHAR 前缀字节
记录实际数据有多长,需要额外保存这个数字:
- 长度 ≤255:1 字节记录长度
- 长度>255:2 字节记录长度
⚠️ 注意:65535 是总字节上限,不是字符。utf8mb4 一个字符最多占 4 字节,所以实际 M 远小于 65535。
CHAR 和 VARCHAR 对比高频考题
- CHAR:浪费空间,查询快;尾部空格保存时丢失。
- VARCHAR:节省空间,查询稍慢;保留字符串内部空格,末尾空格会保留。
比如插入
'ab '(ab 加一个空格)到 varchar,取出来还有空格。
TEXT
- 不能设置默认值
- 不把数据存在行内(行溢出,存在溢出页),读取慢
- 建索引必须指定前缀:
INDEX idx_content(content(100)) - 禁止把短字符串放到 TEXT,开销大
建表示例
CREATE TABLE test_str(
id CHAR(18),
name VARCHAR(50),
article TEXT
);
选型建议
- 固定短字符串:CHAR(身份证,编码)
- 长短不一的普通字符串:VARCHAR(最常用)
- 很长的文本、文章:TEXT
- 超长文章:MEDIUMTEXT
易混点:字符 vs 字节
M 是字符 ,不是字节!utf8mb4 下一个汉字占 4 字节。 varchar(10):最多 10 个汉字 / 字符,不是 10 个字节。
还有二进制字符串(BINARY/VARBINARY、BLOB),也是经常一起考,要不要继续整理?
BLOB 存二进制:图片、文件字节;TEXT 存文本。
⽇期类型:Date、DateTime、TimeStamp、Time、Year
高频考点,重点区分 DATETIME 和 TIMESTAMP
| 类型 | 字节 | 格式 | 取值范围 | 说明 & 场景 |
|---|---|---|---|---|
| DATE | 3 | YYYY-MM-DD |
1000-01-01 ~ 9999-12-31 | 只存日期,没有时分秒;生日、下单日期 |
| TIME | 3 | HH:MM:SS |
-838:59:59 ~ 838:59:59 |
时间,可以存负数、超过 24 小时(用来表示时间间隔),不是只能一天内的时间 |
| YEAR | 1 | YYYY |
1901 ~ 2155 | 只存年份。老项目用,现在很少推荐 |
| DATETIME | 8 | YYYY-MM-DD HH:MM:SS |
1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | 日期 + 时间,不带时区转换,存原始时间。新项目首选! |
| TIMESTAMP | 4 | YYYY-MM-DD HH:MM:SS |
1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC | 时间戳,会自动时区转换,受 session 时区影响;有经典【2038 年溢出问题】 |
✅ 核心考点
TIMESTAMP 原理 底层存的是从 1970-01-01 UTC 开始的秒数,4 字节。 写入时,把当前会话时区 → 转 UTC 存;读取时 UTC 再转回当前会话时区。
⚠️ 时区变了,查出来的时间就变! 上限:2038 年问题,到点溢出,不能存之后时间。
DATETIME:直接保存年月日时分秒,不做时区转换。存的是什么,读出来就是什么,不受时区影响。没有 2038 限制。
自动更新(ON UPDATE CURRENT_TIMESTAMP)
-
TIMESTAMP 旧版本默认自带自动更新;MySQL5.7 之后调整,DATETIME 也支持
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPcreate table test_time(
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
含义:新增时自动填入当前时间;记录被修改时自动更新为当前时间。
开发建表规范:创建时间、更新时间,现在都推荐 DATETIME。
- TIME 特殊点 不是仅仅 00:00:00~23:59:59。 支持大于 24 小时、负数,适合表示时间间隔,比如耗时 300 小时。
- YEAR (2) 废弃!不要用两位年份,会自动猜世纪,坑很多,只用 YEAR(4 位)。
选型推荐
- 只需要年月日 →
DATE(生日,预约日期) - 只存时长 / 间隔 →
TIME - 只存年份 →
YEAR(尽量少用) - 需要完整日期时间:优先 DATETIME(推荐)
- TIMESTAMP:尽量少用。除非你明确需要时区自动转换,并且时间不会超过 2038。
⚠️ 面试高频对比
- DATETIME:8 字节、无时区转换、范围大、无 2038 问题 ✅推荐
- TIMESTAMP:4 字节、带时区转换、范围小、2038 溢出风险
一句话口诀: 时间戳 TIMESTAMP,存秒,受时区影响,2038 翻车; DATETIME 直接存年月日时分秒,不受时区影响,新项目首选。