当前位置: 代码网 > it编程>数据库>Mysql > MySQL数据库原理与实践指南:数据类型

MySQL数据库原理与实践指南:数据类型

2026年07月27日 Mysql 我要评论
在mysql数据库中,数据类型是定义表中列(column)可以存储的数据的类型和格式的关键元素。正确选择和使用数据类型对于数据库的性能、存储效率和数据的完整性至关重要。mysql支持多种数据类型,包括

在mysql数据库中,数据类型是定义表中列(column)可以存储的数据的类型和格式的关键元素。正确选择和使用数据类型对于数据库的性能、存储效率和数据的完整性至关重要。mysql支持多种数据类型,包括数值类型、日期和时间类型、字符串类型等。下面将详细介绍一些常见的数据类型及其应用。

本篇目标:

认识mysql的多种不同的数据类型。

一.数值类型

1.tinyint类型

在mysql 中 tinyint 占用 1 字节(8 bit)

  • tinyint:范围是 -128~127
  • tinyint unsigned:范围是 0~255

下面以一个实例来举例:

首先创建一个数据库,并使用它:

然后创建一张表,表中存在一个类型为tinyint的num,如图:

然后我们插入数据,并验证一下超过tinyint的取值范围会咋样?如图:

可以看出,这个mysql的数据范围溢出和编程语言的数据范围溢出是不同的,区别:

  • mysql字段更看重数据合法性,越界通常拒绝写入
  • 编程语言变量更接近底层整数运算,无符号数会回绕,有符号数溢出则可能出现未定义行为。
  • 数据库需要保证长期保存的数据可靠,所以默认处理通常更加严格。

无符号类型tinyint的演示:

2.int类型

基本信息:

字段名 int

int 占用 4字节(32 bit)

默认是有符号类型

num int

取值范围为:−2^31∼2^31−1

也就是:

-2147483648 ~ 2147483647

使用无符号类型

num int unsigned

取值范围为: 

也就是:

0 ~ 4294967295

3.bit类型

基本语法:

字段名 bit(m)

其中:

  • m 表示存储多少个二进制位
  • m 的范围为 1~64
  • 不写 m 时默认为 bit(1)

例如:

id1 bit(1);
id2 bit(8);

bit(m) 取值范围是:0-2^m-1;

类型位数数值范围
bit(1)10~1
bit(2)20~3
bit(4)40~15
bit(8)80~255
bit(16)160~65535
bit(64)640~2^64-1

代码演示:

但是我们可能会发现一个奇怪的现象,这个a在数据库中居然不显示或者显示的是字符?如图:

这是因为bit字段在显示时,可能会按照ascii码对应的值显示,如果我们希望以10进制来查看可以进行一下的操作:

二.小数类型

1.float类型

语法:

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

案例:

小数:float(4,2)表示的范围是-99.99 ~ 99.99,mysql在保存值时会进行四舍五入

操作如图:

其实我们自己操作的时候,会发现例如99.991,99.994都是被四舍五入为99.99的,但是如果是

99.995则会四舍五入为100,明显超出了这个取值范围,如图:

注意:

没有指定总位数和小数位数,那么它使用标准的单精度浮点数,通常占 4 字节

可表示的非零范围大致为:

负数:-3.402823466e+38 ~ -1.175494351e-38
零:  0
正数: 1.175494351e-38 ~ 3.402823466e+38

不过,范围很大不代表能精确保存这么多位。float 通常只能保证约 6~7位有效数字

2.decimal类型

基本格式:

decimal(m, d)

其中:

  • m:总有效位数,包括整数和小数部分
  • d:小数位数
  • 整数部分最多有 m - d
  • m 最大为 65
  • d 最大为 30,并且不能大于 m

例如:

price decimal(5, 2)

表示:

总共最多5位
小数部分占2位
整数部分最多3位

取值范围为:

-999.99 ~ 999.99

代码实例:

其实,我们会发现这个decimal和float的使用差不多,但是decimal更精确,区别如图:

注意:如果d被省略,默认为0.如果m被省略, 默认是10。所以如果希望小数的精度高,推荐使用decimal

三.字符串类型

1.char类型

基本格式:

char(n)

其中 n 表示最多保存的字符数不是字节数范围一般是:0~255

例如:

name char(5)

最多保存5个字符,在 mysql 的 utf8(即 utf8mb3)字符集中,每个字符最多占3字节

不同字符占用的字节数不同:

字符utf8占用字节
英文字母 a1字节
数字 11字节
常见中文 3字节
部分符号2~3字节
emoji 😀无法保存

例如:

abc       → 3字节
中国      → 6字节
abc中国   → 9字节

实例演示:

2.varchar类型

基本格式:

varchar(l): 可变长度字符串,l表示字符长度

其中,n表示最多可以保存的字符数,不是字节数,,最大为65535个字节

例如:

name varchar(20)

表示最多保存20个字符,无论是英文还是中文。

如图:

其实当我们将最大长度修改为65535时,就发现会有问题,如图:

其实我们一直要明白一个问题:l是字符数,而非字节数

关于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字节)。

然后我们将字符数修改为最大,如图:

原因:varchar(21844)的理论最大值,是在utf8mb3下几乎把整行空间全部分给这一个字段计算出来的:21844×3=65532字节

但是你的表中不只有name,还有:

id

假设idint,它还要占4字节。此外还需要长度信息和null标记:

name最大内容:21844 × 3 = 65532字节
varchar长度信息:约2字节
id字段:4字节
null标记等:至少还需要一些空间

总大小已经超过:

65535字节

因此创建失败。

3.两者区别

varchar的“变长”指:

字段实际占用的空间,会随着存入字符串的长度发生变化。

varchar为什么叫变长字符串?

假设定义:

name varchar(10)

它表示最多保存10个字符,但不会始终占用10个字符的空间。

分别插入:

insert into test values ('abc');
insert into test values ('abcdefgh');

大致存储情况为:

abc       → 保存3个字符的数据
abcdefgh  → 保存8个字符的数据

此外,varchar需要使用1或2字节记录字符串的实际长度:

实际字符串内容 + 长度信息

所以它叫可变长度字符串类型。

char为什么叫定长字符串?

假设定义:

name char(10)

无论实际字符串有多长,字段都按照固定的10字符长度进行处理。

插入:

insert into test values ('abc');

逻辑上相当于在后面补充空格:

'abc       '

查询时,mysql通常会把末尾补充的空格去掉,所以看到的仍然是:

abc

四.日期和时间类型

1.date类型

date用于保存日期,不保存具体时间。

基本格式:

yyyy-mm-dd

取值范围:

1000-01-01 ~ 9999-12-31

占用空间:

3字节

代码演示:

2.datetime类型

datetime用于保存日期和具体时间

基本格式:

yyyy-mm-dd hh:mm:ss

取值范围:

1000-01-01 00:00:00
~
9999-12-31 23:59:59

基础占用空间:

5字节

3.timestamp类型

timestamp也用于保存日期和具体时间

基本格式:

yyyy-mm-dd hh:mm:ss

基础占用空间:

4字节

常见取值范围:

1970-01-01 00:00:01 utc
~
2038-01-19 03:14:07 utc

4.代码演示

可以看出当我们添加数据时,时间戳自动补 上当前时间。

然后,我们更新一下数据,如图:

所以更新数据时,时间戳也会更新成当前时间

五.enum和set

语法:

enum:枚举,“单选”类型;
enum('选项1','选项2','选项3',...);

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

set:集合,“多选”类型; set('选项值1','选项值2','选项值3', ...);

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

实例:

我们也可以使用数字插入,如图:

解释:我们使用数字即下标(从1开始)时,可以看出gender是很好的匹配的,但是为什么hobby时,用5,3的时候会出现其他的hobby呢?说明set类型的集合的数字并不可以当成下标,其实这是位图,一个是0101,一个是0011。

hobby中每个选项对应一个二进制位:

爱好二进制位十进制权值
登山00011
游泳00102
篮球01004
武术10008

有如下数据,想查找所有喜欢登山的人:

使用如下查询语句:

但是我们发现查询这个登山的人时,仅查询了lilei的,但是其他带有登山的去不显示出来,那咋办?

所以我们可以使用集合查询使用find_ in_ set函数: find_in_set(sub,str_list);

规则:如果sub在str_list中,则返回下标;如果不在,返回0; str_list用逗号分隔的字符串。

操作如图:

用find_in_set来查询爱好登山的人:

到此这篇关于mysql数据库原理与实践记录:表的约束的文章就介绍到这了,更多相关mysql表的约束内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com