当前位置: 首页 > news >正文

【MySQL】MySQL中的数据类型详解

目录

一、MySQL经典数据类型一览:

二、数值类型:

整形家族:

BIT:

三、小数类型:

float:

decimal:

四、字符串类型:

char:

varchar:

char和varchar区别:

五、时间日期类型:

六、enum与set类型:

enum:

set:

集合中的查询:


一、MySQL经典数据类型一览:

数值类型:

整数类型:

类型存储空间有符号范围无符号范围示例
TINYINT1 字节-128 ~ 1270 ~ 255年龄
SMALLINT2 字节-32768 ~ 327670 ~ 65535小范围计数
MEDIUMINT3 字节-8388608 ~ 83886070 ~ 16777215中等范围数值
INT4 字节-2³¹ ~ 2³¹-10 ~ 2³²-1用户ID、订单号
BIGINT8 字节-2⁶³ ~ 2⁶³-10 ~ 2⁶⁴-1大整数(如分布式ID)
  • 使用unsigned禁止负数,扩大正数范围
  • BOOL类型在MySQL中表现是tinyint的别名,存储0(假)或1(真)

小数类型

类型存储空间描述示例
FLOAT4 字节单精度浮点数,近似值科学计算数据
DOUBLE8 字节双精度浮点数,更高精度近似值高精度测量值
DECIMAL(M,D)变长(M+2字节)精确小数,M=总位数,D=小数位金额 DECIMAL(10,2)
  • decimal适合精确计算(如财务数据),避免浮点误差
  • float和double可能丢失精度,适合非精确计算

日期和时间类型

类型存储空间格式范围示例
DATE3 字节YYYY-MM-DD1000-01-01 ~ 9999-12-31生日、事件日期
TIME3 字节HH:MM:SS-838:59:59 ~ 838:59:59持续时间
DATETIME8 字节YYYY-MM-DD HH:MM:SS1000-01-01 00:00:00 ~ 9999-12-31 23:59:59订单创建时间
TIMESTAMP4 字节Unix时间戳1970-01-01 00:00:01 UTC ~ 2038-01-19 UTC最后登录时间(自动更新)
YEAR1 字节YYYY1901 ~ 2155年份

字符串类型

类型最大长度描述示例
CHAR(n)255 字符定长字符串,适合短且固定长度国家代码 CHAR(2)
VARCHAR(n)65535 字节变长字符串,适合长度变化数据用户名、地址

特殊类型

类型描述示例
ENUM枚举值(单选)性别 ENUM('男','女')
SET集合值(多选)标签 SET('A','B','C')

二、数值类型:

整形家族:

数据类型字节数带符号最小值带符号最大值无符号最小值无符号最大值
TINYINT1-1281270255
SMALLINT2-3276832767065535
MEDIUMINT3-83886088388607016777215
INT4-2147483648214748364704294967295
BIGINT8-92233720368547758089223372036854775807018446744073709551615

首先用SQL语句创建一个表,在其中测试smallint和tinyint unsigned

注意:SQL语句中创建无符号的类型是在类型后面加上unsigned

SQL语句:

create table if not exists student(id smallint,age tinyint unsigned
};

接着我们向表中插入在其范围中的语句,是能够插入的

那我们试试向表中插入不在其中范围的语句:

当向age插入负数的时候,是不可以的,因为其是无符号的,是非负的,会插入失败

也不能插入的数据不在它们表示的范围中,也会失败的

由此可见:

  • MySQL对数据的检测是严格的,会直接拦截非法的数据插入
  • 也就是说,只要是插入成功的数据,就一定是合法的

BIT:

基本语法:

bit[(m)]:这是位字段类型,m表示每个值的位数,范围是1~64,如果不写m,默认为1

create table t1( sex bit(1), a bit(2), aa bit(8) );

接着我们向其中插入些许数据:

可以看到这是以十六进制进行存储的

那么我们插入其他不成功的数据看看:

仔细观察,我们会发现其数据范围是按照位数来进行判断的:

  • bit(1)代表着只有1位 所以我们只能插入1或者0
  • bit(2)代表着有2位 也就是00 01 10 11代表着0,1,2,3
  • bit(8)代表着有8位 所以最大是1111 1111也就是1 0000 0000 - 1的结果 也就是255

如上以此类推

三、小数类型:

float:

基本语法:

float[(m,d)] [unsigned]:其中m表示总共显示的长度,表示小数点后面的位数,其占4字节

create table t2(
浮点数 float(6,3)
);

这样,其范围按照定义来说是-999.999~999.999,在该范围下的数据都能够成功插入

这里如果插入的时候后面比标准的小数点要少的话,会自动补齐0

这里如果插入的时候后面比标准的小数点要多的话,会四舍五入

浮点数如果是无符号的话,比如 float(6,3) unsigned 这样的话其范围是把负数那部分直接砍掉,就是0~999.999

float存在精度损失:

当对其进行插入操作后,然后在进行查看,发现其精度存在损失

double和float的使用基本是一样的,只是存储的范围大些,要想追求高精度,就需要使用类型decimal

decimal:

decimal使用方法大致和float基本差不多,在存储浮点数时,decimal能够更好地保证小数的精度

首先创建一个表,其类型为decimal

然后向表中插入和之前float丢失的精度的数据,然后进行查看

所以:

对精度的要求不是很高的,使用float或者double存储浮点数即可
对精度的要求很高的,使用decimal存储浮点数

四、字符串类型:

char:

char(L)是固定字符串,其中L是存储的长度,最大为255

首先创建一个表,里面有一个字段名称为name,类型为char(5)

所以,我们向表中插入字符串的长度不能超过5个,这个无论是汉字还是英文字母都是这样的

这里char不是按照字节来进行查看的,这里和C/C++是不一样的,这里是按照个数来看的,无论是英文字母还是汉字,都是满足其对应的个数即可

这样,用户在编码的时候就不必在意字节上的差异了

最后注意char类型最大长度为255

varchar:

char是固定字符串,在定义后是不能增加的,varchar是变长字符串,其最大是65535个字节

当对其进行插入的时候,发现5个字符能够插入,但是多了就不能够插入了

那么这个变长字符串的变长体现在哪里呢?

如上,当给varchar类型分配空间后,这里是分配了5个字符的空间,但是如果实际插入的字符串长度不足5个,比如说3个,那么就只会只使用3个字符空间,如果实际插入的字符为4个,那么就只会只使用4个字符空间,这里的变长体现在varchar类型中,会根据实际插入的字符串长度,动态分配空间,达到变长的效果

所以varchar类型是指定字符个数的上限的

上面说varchar支持的是65535个字节,那么我们设置一下看看

发现这里是不行的,会发现这里是21845,为什么呢?----- 我们知道这里是存的是中文字符,一个中文字符在utf8编码中占3个字节,那么65535 / 3 = 21845,这就是varchar支持的最大字符串长度

那么我们修改为21845

发现居然又错了,上述报错翻译过来就是:

行大小太大。使用的表类型(不计算 BLOB)的最大行大小为 65535。这包括存储开销,请查看手册。您必须将某些列更改为 TEXT 或 BLOB

实际上,对于中文字符串来说,其空间不仅仅只是记录数据的,还需要1~2个长度标识字节,还有1字节来存储其他控制信息

所以实际上,最长字符串长度为(65535-3)/3=21844

char和varchar区别:

对比维度CHARVARCHAR
存储方式固定长度,填充空格至定义长度可变长度,存储实际数据+长度标识(1-2字节)
空间占用固定(定义长度)动态(实际长度+长度标识)
存取性能更快(直接定位固定长度)略慢(需解析长度标识)
最大字符数255(与字符集无关)受字符集影响(如utf8:约21844字符)
尾部空格处理存入时自动补空格,检索时自动去除保留存入时的尾部空格
适用场景短且定长的数据(如性别代码、MD5哈希)长度不定的数据(如用户名、地址)

五、时间日期类型:

常用的时间类型有三种,分别是:

  • date:其格式为YYYY-MM-DD,占用3字节
  • datetime:其格式为YYYY-MM-DD HH:MM:SS,占用8字节
  • timestamp:这是时间戳,其格式为YYYY-MM-DD HH:MM:SS,占用4字节

接着向前两个插入数据:这是比较简单的

但是关于d3,也就是时间戳

从 MySQL 5.6.6 起,

TIMESTAMP列如果没有显式指定DEFAULT值

就不会在自动默认给CURRENT_TIMESTAMP

除非用户明确加上DEFAULT CURRENT_TIMESTAMP 或 ON UPDATE CURRENT_TIMESTAMP

否则该字段就是普通的NULLABLE列

如果已经创建了,可以用语句:ALTER TABLE t7
MODIFY COLUMN d3 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;来给t7表的d3列加上缺省

这样如果是缺省的TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE就能够当时间戳在更新时就会自动刷新,如update修改数据的时候,但是这里修改表中的列如id,或者这个列的类型是不会刷新时间戳的

如下,t8表

向t8表中插入数据id = 1,这个时候不用管时间戳,他会自动填入的

当对表中的数据进行修改,比如将id的值从1修改为0

这样的话TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE修饰的时间戳就会自动更新,TIMESTAMP DEFAULT CURRENT_TIMESTAMP修饰的时间戳不会自动更新

这里是修改数据才会使其更新,如果修改表中的字段是不会引发更新的,比如将id修改为idd是不会引发更新的

六、enum与set类型:

enum:

enum被称为枚举类型,他是用于提供一批元素,然后只能选择其中的一个

我们创建一个表,其中用枚举表示男或者女

这样,在其中查看

当向其中进行插入的时候,对sex进行插入的时候,只能从其列表中进行选择一个元素进行插入

insert into t9 values ('张三','男');
insert into t9 values ('李四','女');

如果是列表中不存在的,或者是插入多个,都是不可以的 

如果列表中的元素字符特别长,不想打字,那么也可以使用数字插入,从1开始对应着列表中的第一个,往后依次++,在上述案例中,男就是对应的1,女就是对应的2

当然,插入没有对应的数字也是不行的

set:

这个被称为集合类型,是支持多选的,用法和enum差不多

我们可以在创建表的时候进行set类型的创建,也可以对已经创建好的表进行增加

alter table t9 add (drink set('可乐','雪碧','茶π','红牛','阿萨姆'));

当向其中进行插入的时候,对drink进行插入的时候,只能从其列表中可以选择多个元素进行插入

insert into t9 values ('张三','男','可乐,雪碧,红牛');
insert into t9 values ('李四','女','茶π,阿萨姆');

同样,也可以使用数字进行插入

上述插入了12345,感觉像是对应着上述的5中品牌

但是查看的时候:

如上,红框框中是对应着上述的五条语句的,但是发现结果不是预期

这是为什么呢?

实际上,这是类似于二进制的存储方式的

当为1的时候,也就是从小到大加一,然后在倒过来看

当为2的时候,进行+1,然后就是雪碧为1,当倒过来看也就是2

当为3的时候,在进行加1,此时就是11000,倒过来就是00011就是3... 往后以此类推

所以根据上述规律,如果全部都喜欢的话,就是 11111 也就是1 00000 也就是2^5-1也就是31

发现正如我们所料

这里有一个奇怪的,如果我们插入0,那么会发现其对应的不是NULL,而是空,这里NULL和空是不等价的,NULL表示什么都插入,空表示插入了这个类型,他是存在的,但是此时为空

集合中的查询:

查询enum

这个比较简单,因为其是唯一的

在查询的时候直接加上 where sex='女'即可

查询set

如果像查询enum一样,那么查询出来的仅仅是只有一个的

如果我们想查询包含可乐的,就需要借助函数find_in_set(str, strlist)

其作用是查询strlist中是否存在str,如果查询到了,就返回对应位置的下标(注意是从1开始的),如果没查到就返回0

select * from t9 where find_in_set('可乐',drink);

这样就能够查看所有包含可乐的了

如果想查询喜欢可乐和雪碧的,就需要用and连接

select * from t9 where find_in_set('可乐',drink) and find_in_set('雪碧',drink);

相关文章:

  • 【前端】【面试】【业务场景】前端如何获取并生成设备唯一标识
  • 使用pyinstaller打包fastapi项目的问题记录
  • 01-初识前端
  • 级联vs端到端、全双工、轮次检测、方言语种、商业模式…语音 AI 开发者都在关心什么?丨Voice Agent 学习笔记
  • 深度学习3.5 图像分类数据集
  • 每日算法-250421
  • Java 并发包核心机制深度解析:锁的公平性、异步调度、AQS 原理全解
  • 【MySQL】:数据库事务管理
  • JavaEE--2.多线程
  • 把dll模块注入到游戏进程的方法_基于文件修改的注入方式
  • MCP:AI时代的“万能插座”,开启大模型无限可能
  • SvelteKit 最新中文文档教程(22)—— 最佳实践之无障碍与 SEO
  • 进程与线程:02 多进程图像
  • 在统信UOS 1060上实现自动关机
  • 高防IP能抵御哪些类型的网络攻击?
  • Buildroot、BusyBox与Yocto:嵌入式系统构建工具对比与实战指南
  • 辛格迪客户案例 | 苏州富士莱医药GMP培训管理(TMS)项目
  • 深度学习3.3 线性回归的简洁实现
  • XXL-JOB 深入理解教程
  • 【MySQL】表的约束(主键、唯一键、外键等约束类型详解)、表的设计
  • 在现代东京,便利店如何塑造了饮食潮流、生活方式和日本社会
  • 普京:俄方积极对待任何和平倡议
  • 安徽一季度GDP为12265亿元,同比增长6.2%
  • 江西省人大教育科学文化卫生委员会主任委员王水平被查
  • 上海明天有雷雨、大风,下周气温在春日舒适区间
  • 五一假期出行预订进入高潮:酒店搜索热度翻倍,“请4休11”拼假带动长线游