【MySQL数据库学习】(MySQL数据类型)


🔥承渊政道: 个人主页
❄️个人专栏: 《C语言基础语法知识》 《数据结构与算法》 《C++知识内容》 《Linux系统知识》 《算法刷题指南》 《测评文章活动推广》 《大模型语言路线学习》 《MySQL数据库学习》
✨逆境不吐心中苦,顺境不忘来时路!✨ 🎬 博主简介:

在学习 MySQL 数据库的过程中,数据类型是一个非常基础但又十分重要的知识点.无论是创建数据表、设计字段结构,还是后续进行数据存储、查询优化和性能调优,合理选择数据类型都会直接影响数据库的存储效率、查询速度以及数据的准确性.很多初学者在刚接触 MySQL 时,可能会简单地把数字都用 INT,文本都用 VARCHAR,时间都用DATETIME.虽然这样在一些简单场景下可以正常使用,但随着业务复杂度提升,如果数据类型选择不合理,就可能带来存储空间浪费、查询性能下降,甚至数据精度丢失等问题.本文将围绕 MySQL 中常见的数据类型展开学习,包括数值类型、字符串类型、日期时间类型等内容,帮助大家理解不同数据类型的特点、使用场景以及选择方式.通过本文的学习,你将能够更加清晰地掌握 MySQL 数据类型的基础知识,并在实际建表时做出更合理的字段设计.废话不多说,下面跟着小编的节奏🎵一起去疯狂的学习吧!

目录

1.数据类型

1.1数据类型分类

这表是在总结 MySQL 常见数据类型,按用途分成几类:数值、文本/二进制、时间日期、字符串枚举集合.

1.数值类型

用于存数字.

BIT(M)

位类型,M 表示位数,默认是1,范围通常是1到64.适合存二进制位,比如开关状态.

TINYINT UNSIGNED

很小的整数.

有符号范围:-128 ~ 127

无符号范围:0 ~ 255

常用于状态值、年龄、小范围编号.

BOOL

布尔类型,用来表示真/假.

在 MySQL 中通常等价于 TINYINT(1),0 表示 false,1 表示 true.

SMALLINT UNSIGNED

小整数.

有符号范围:-32768 ~ 32767

无符号范围:0 ~ 65535

INT UNSIGNED

普通整数,最常用.

有符号范围大约是:-2^31 ~ 2^31-1

无符号范围:0 ~ 2^32-1

适合存用户 ID、数量、编号等.

BIGINT UNSIGNED

大整数.

有符号范围:-2^63 ~ 2^63-1

无符号范围:0 ~ 2^64-1

适合存特别大的编号,比如订单号、雪花 ID.

FLOAT(M,D) UNSIGNED

单精度浮点数.

M 表示总长度,D 表示小数位数.占 4 字节.

适合对精度要求不高的小数.

DOUBLE(M,D) UNSIGNED

双精度浮点数.占 8 字节.

FLOAT 精度更高,但仍然可能有精度误差.

DECIMAL(M,D) UNSIGNED

定点小数.

M 是总位数,D 是小数位数.

适合金额、价格、财务数据,因为它比 FLOAT/DOUBLE 更精确.

2.文本、二进制类型

用于存字符串或二进制内容.

CHAR(size)

固定长度字符串,最大 255.

比如 CHAR(10),不够 10 位也会按固定长度存储.

适合长度固定的数据,比如性别、国家代码、固定编号.

VARCHAR(size)

可变长度字符串,最大 65535.

实际占用空间按内容长度变化.

最常用,适合用户名、邮箱、标题、地址等.

BLOB

二进制数据类型.

可以存图片、文件、音频等二进制内容,但实际开发中通常更推荐存文件路径或 URL.

TEXT

大文本类型.

支持全文索引,不支持默认值.

适合文章内容、评论、简介等长文本.

3.时间日期类型

用于存日期和时间.

DATE

日期类型,格式是:

sql 复制代码
yyyy-mm-dd

例如:

sql 复制代码
2026-05-26

DATETIME

日期 + 时间,格式是:

sql 复制代码
yyyy-mm-dd hh:mm:ss

例如:

sql 复制代码
2026-05-26 14:30:00

TIMESTAMP

时间戳类型,通常也显示为日期时间格式.

它和时区关系更密切,常用于记录创建时间、更新时间.

4.String 类型中的特殊类型

ENUM 类型

枚举类型,只能从预先定义好的值中选择一个.

例如:

sql 复制代码
gender ENUM('男', '女', '未知')

这个字段只能存 '男''女''未知' 其中一个.

SET 类型

集合类型,也是在建表时预先定义可选值,但一个字段可以选择多个值.

例如:

sql 复制代码
hobby SET('篮球', '足球', '音乐', '阅读')

可以存:

sql 复制代码
'篮球,音乐'

也就是说,ENUM多选一 ,SET多选多.


1.2数值类型

这表是在说明 MySQL 整数类型的存储字节数和取值范围.

表头含义:

列名 含义
类型 MySQL 整数数据类型
字节 该类型占用的存储空间
最小值 该类型能存的最小整数
最大值 该类型能存的最大整数

其中"带符号的/无符号的"表示:

带符号 signed :可以存负数、0、正数.

无符号 unsigned:只能存 0 和正数,但正数范围会变大.


1.TINYINT

1 个字节.

带符号范围:

sql 复制代码
-128 ~ 127

无符号范围:

sql 复制代码
0 ~ 255

适合存很小的数字,比如状态码、性别、开关值等.

2.SMALLINT

2 个字节.

带符号范围:

sql 复制代码
-32768 ~ 32767

无符号范围:

sql 复制代码
0 ~ 65535

适合存较小范围的整数,比如年龄、库存数量、小编号等.

3.MEDIUMINT

3 个字节.

带符号范围:

sql 复制代码
-8388608 ~ 8388607

无符号范围:

sql 复制代码
0 ~ 16777215

它介于 SMALLINTINT 之间,实际开发中用得比 INT 少.

4.INT

4 个字节.

带符号范围:

sql 复制代码
-2147483648 ~ 2147483647

无符号范围:

sql 复制代码
0 ~ 4294967295

这是最常用的整数类型,比如用户 ID、商品 ID、数量统计等.

5.BIGINT

8 个字节.

带符号范围:

sql 复制代码
-9223372036854775808 ~ 9223372036854775807

无符号范围:

sql 复制代码
0 ~ 18446744073709551615

适合存非常大的整数,比如大规模系统中的订单号、流水号、雪花 ID 等.


1.2.1tinyint类型

我们建一张名字叫t1的表:

sql 复制代码
create table t1(
    num tinyint
    );

我们向表中插入一些数据:

sql 复制代码
insert into t1 values (-128);
insert into t1 values (127);
insert into t1 values (0);
insert into t1 values (-1);
insert into t1 values (1);

数值越界测试:

sql 复制代码
insert into t1 values (-129);
insert into t1 values (128);
insert into t1 values (130);

越界插入非法数值,导致报错!

我们建一张名字叫t2的表:

sql 复制代码
create table t2(
    num tinyint unsigned
    );

我们向表中插入一些数据:

sql 复制代码
insert into t2 values(0);
insert into t2 values(255);
insert into t2 values(100);

数值越界测试:

sql 复制代码
insert into t2 values(-1);
insert into t2 values(256);

越界插入非法数值,导致报错!

说明:

在MySQL中,整型可以指定是有符号的和无符号的,默认是有符号的.

可以通过UNSIGNED来说明某个字段是无符号的.

如果我们向 mysql 特定的类型中插入不合法的数据,MySQL 一般都是直接拦截我们,不让我们做对应的操作!反过来,如果我们已经有数据被成功插入到mysql中了,一定插入的时候是合法的!

上面介绍的是整型类型的,其他类型自己推导.

注意:尽量不使用unsigned,对于int类型可能存放不下的数据,int unsigned同样可能存放不下,与其如此,还不如设计时,将int类型提升为bigint类型.


1.2.2bit类型

基本语法:

bash 复制代码
bit[(M)] : 位字段类型。M表示每个值的位数,范围从1到64。如果M被忽略,默认为1。

BIT 是 MySQL 中的位类型,用来存储二进制位数据.

例子

sql 复制代码
CREATE TABLE test_bit (
    b1 BIT,
    b2 BIT(4),
    b3 BIT(8)
);

含义是:

字段 含义
b1 BIT 默认 BIT(1),只能存 1 位
b2 BIT(4) 存 4 位二进制数
b3 BIT(8) 存 8 位二进制数

创建名字t3的表,插入bit类型的字段:

sql 复制代码
create table t3(
    id int,
    online bit(1)
    );

向表中插入一些数据:

sql 复制代码
insert into t3 (id,online) values(123,0);
insert into t3 (id,online) values(124,1);

发现很怪异的现象,online的插入的数据0和1没有出现!

bit使用的注意事项:bit字段在显示时,是按照ASCII码对应的值显示.

如果想要数据回显,可以进行以下这种操作!

sql 复制代码
select id, hex(online) from t3;

如果我们有这样的值,只存放0或1,这时可以定义bit(1).这样可以节省空间.

当插入数据过大了,会导致越界啦!

sql 复制代码
insert into t3 (id,online) values(123,3);
insert into t3 (id,online) values(123,5);
insert into t3 (id,online) values(123,2);

1.2.3小数类型

1.2.3.1float

语法:

bash 复制代码
float[(m, d)] [unsigned] : M指定显示长度,d指定小数位数,占用空间4个字节

案例:

bash 复制代码
小数:float(4,2)表示的范围是-99.99 ~ 99.99,MySQL在保存值时会进行四舍五入。

我们创建一张名为t4的表进行验证一下:

向表中插入一些数据:

这些插入的数据都是没有问题的,但是超过那个范围呢?就是告诉我们无法插入!

案例:

bash 复制代码
如果定义的是float(4,2) unsigned 这时,因为把它指定为无符号的数,范围是 0 ~ 99.99

我们创建一张名为t5的表进行验证一下:

我们发现超出范围的数据是无法被插入的!


1.2.3.2decimal

语法:

bash 复制代码
decimal(m, d) [unsigned] : 定点数m指定长度,d表示小数点的位数

decimal(5,2) 表示的范围是 -999.99 ~ 999.99

decimal(5,2) unsigned 表示的范围 0 ~ 999.99

decimal和float很像,但是有区别:

float和decimal表示的精度不一样

创建名叫t6的表进行验证一下:

我们向表中插入数据,看看数据显示情况:

如果我们希望某个数据表示高精度,选择decimal

说明:float表示的精度大约是7位.

decimal整数最大位数m为65.支持小数最大位数d是30.如果d被省略,默认为0.如果m被省略,默认是10.建议:如果希望小数的精度高,推荐使用decimal.


1.3字符串类型

1.3.1char

语法:

bash 复制代码
char(L): 固定长度字符串,L是可以存储的长度,单位为字符,最大长度值可以为255

创建名叫t7的表验证一下:

我们向表中插入数据,看看数据显示情况:

说明:char(2)表示可以存放两个字符,可以是字母或汉字,但是不能超过2个,最多只能是255


1.3.2varchar

语法:

bash 复制代码
varchar(L): 可变长度字符串,L表示字符长度,最大长度65535个字节

创建名叫t8的表验证一下:

我们向表中插入数据,看看数据显示情况:

说明:

关于varchar(len),len到底是多大,这个len值,和表的编码密切相关:

varchar长度可以指定为0到65535之间的值,但是有1 - 3 个字节用于记录数据大小,所以说有效字节数是65532.

当我们的表的编码是utf8时,varchar(n)的参数n最大值是65532/3=21844因为utf中,一个字符占用3个字节,如果编码是gbk,varchar(n)的参数n最大是65532/2=32766(因为gbk中,一个字符占用2字节).

那么问题来了,当我改成6636,报错的信息为什么说最大说16383?

因为 VARCHAR(N) 里的 N 是字符数,不是字节数.

我执行的是:

sql 复制代码
alter table t8 modify name varchar(65536);

MySQL 需要判断这个字段最多可能占多少 字节 .如果你的表或字段字符集是 utf8mb4,每个字符最多占 4 个字节,所以:

text 复制代码
65536 个字符 × 4 字节 = 262144 字节

这远超 VARCHAR 在 MySQL 中的行内最大限制.

报错里显示的:

text 复制代码
max = 16383

是因为在 utf8mb4 下:

text 复制代码
16383 × 4 = 65532 字节

再加上 VARCHAR 自身需要的长度字节,刚好接近 MySQL 单行最大约 65535 字节的限制.所以 MySQL 告诉你:在当前字符集下,这个字段最大只能是 varchar(16383) 左右.

可以验证字符集:

sql 复制代码
show create table t8;

或者:

sql 复制代码
show full columns from t8;

如果用的是 latin1 这种单字节字符集,理论最大值会接近:

sql 复制代码
varchar(65532)

但如果是 utf8mb4,最大就是大约:

sql 复制代码
varchar(16383)

如果你确实需要存很长文本,应该改用:

sql 复制代码
TEXT

例如:

sql 复制代码
alter table t8 modify name text;

总结:65535 是字节上限,不是字符上限;utf8mb4 每字符最多4字节,所以最大字符数约等于 65535 / 4 = 16383.


1.3.3char和varchar比较

实际存储 char(4) varchar(4) char 占用字节 varchar 占用字节
abcd abcd abcd 4*3=12 4*3+1=13
A A A 4*3=12 1*3+1=4
Abcde × × 数据超过长度 数据超过长度

如何选择定长或变长字符串?

如果数据确定长度都一样,就使用定长(char),比如:身份证,手机号,md5

如果数据长度有变化,就使用变长(varchar),比如:名字,地址,但是你要保证最长的能存的进去.

定长的磁盘空间比较浪费,但是效率高.

变长的磁盘空间比较节省,但是效率低.

定长的意义是,直接开辟好对应的空间

变长的意义是,在不超过自定义范围的情况下,用多少,开辟多少.


1.4日期和时间类型

常用的日期有如下三个:

date :日期 'yyyy-mm-dd' ,占用三字节

datetime:时间日期格式 'yyyy-mm-dd HH:ii:ss' 表示范围从 1000 到 9999 ,占用八字节

timestamp:时间戳,从1970年开始的 yyyy-mm-dd HH:ii:ss 格式和 datetime 完全一致,占用四字节

创建名为t9的表,并插入数据:

早期 MySQL 或关闭了 explicit_defaults_for_timestamp 时的行为:

sql 复制代码
create table t9 (
  t1 date,
  t2 datetime,
  t3 timestamp
);

在某些旧版本或旧配置下,第一个 timestamp 字段会被 MySQL 自动加上默认属性,相当于变成:

sql 复制代码
t3 timestamp not null
  default current_timestamp
  on update current_timestamp

所以图片里:

插入时不写 t3

sql 复制代码
insert into birthday(t1,t2)
values('1997-7-1','2008-8-8 12:1:1');

t3 会自动变成当前时间.

更新其他字段时:

sql 复制代码
update birthday set t1='2000-1-1';

t3 又会自动更新成当前时间。


但我的自己的表里,desc t9; 已经显示得很清楚:

text 复制代码
Field | Type      | Null | Default
t3    | timestamp | YES  | NULL

说明你的 t3 实际定义是:

sql 复制代码
t3 timestamp null default null

所以我插入数据时没有给 t3 赋值,它当然就是:

text 复制代码
NULL

如果想实现图片里的效果,需要明确写出来:

sql 复制代码
create table birthday (
  t1 date,
  t2 datetime,
  t3 timestamp default current_timestamp on update current_timestamp
);

或者修改我已有的表:

sql 复制代码
alter table t9
modify t3 timestamp default current_timestamp on update current_timestamp;

之后再插入时不写 t3,它就会自动填当前时间;更新其他字段时,t3 也会自动更新.


1.5enum和set

语法:

1.enum:枚举,"单选"类型;

enum('选项1','选项2','选项3',...);

该设定只是提供了若干个选项的值,最终一个单元格中,实际只存储了其中一个值;而且出于效率考虑,这些值实际存储的是"数字",因为这些选项的每个选项值依次对应如下数字:1,2,3,...最多65535个;当我们添加枚举值时,也可以添加对应的数字编号.

2.set:集合,"多选"类型;

set('选项值1','选项值2','选项值3', ...);

该设定只是提供了若干个选项的值,最终一个单元格中,设计可存储了其中任意多个值;而且出于效率考虑,这些值实际存储的是"数字",因为这些选项的每个选项值依次对应如下数字:1,2,4,8,16,32,...最多64个.

说明:不建议在添加枚举值,集合值的时候采用数字的方式,因为不利于阅读.

查询性别为男的信息:

集合查询使用find_ in_ set函数:

🚀真正的勇者不是流泪的人,而是含泪奔跑的人!


敬请期待下一篇文章内容


每日心灵鸡汤: 海压竹枝低复举,风吹山角晦还明!

今天看到一句很棒的诗:"海压竹枝低复举,风吹山角晦还明."它的意思是"乌云终将消散,黑暗终将过去,光明终会重现,人生在世没有事事如意,能屈能伸,黑暗过后自有万丈光芒在等你".谨以此句,送给我也送给你们.所有的经历都可以成为成长,希望大家都不要再因为任何人任何事而否定自己.总会有不如意的,生活从来都是泥沙俱下,鲜花与荆棘并存,我们带着疲惫满满来,慢一点也好,步子小也好,走在往前走就好.所以,做回自己,和朋友保持联系,按时睡觉不要再胡思乱想,爱情很好,没有也好,我们这样年纪本就该是骄傲的."海压竹枝低复举,风吹山角晦还明."我们终将上岸,阳光万里.

相关推荐
梦想的颜色1 小时前
MySQL 三大日志:Redo Log、Undo Log 和 Binlog 完全解析
数据库·mysql·数据库架构
WangX-西石油1 小时前
DVWA靶场Low级别Brute Force学习
学习·web安全·网络安全
KaMeidebaby1 小时前
卡梅德生物技术快报|蛋白修饰调控 NETosis 分子机制及实验研究进展
前端·数据库·人工智能·算法·百度
段一凡-华北理工大学1 小时前
工业领域的Hadoop架构学习~系列文章08:Flink流处理引擎
人工智能·hadoop·学习·架构·flink·高炉炼铁·高炉炼铁智能化
睡不醒男孩0308231 小时前
行业解决方案一:CLup助力金融行业构建自主可控PostgreSQL高可用数据库平台
数据库·金融·clup
海鸥-w2 小时前
前端学习python第三天笔记整理(list 列表,str字符串,tuple元组,set集合,dect,函数,类型注解)
前端·python·学习
Upsy-Daisy2 小时前
IOTA 学习笔记(六):Move 语言入门
笔记·学习
段一凡-华北理工大学2 小时前
工业领域的Hadoop架构学习~系列文章07:Spark内存计算引擎
大数据·人工智能·hadoop·学习·架构·高炉炼铁·高炉炼铁智能化
Bechamz2 小时前
大数据开发学习Day46
大数据·学习