mysql数据类型——认识并掌握数据类型
文章目录
- mysql数据类型的认识与掌握
- 总体认识数据的分类
- 数值类型
- TINYINT类型及其余整数类型
- BOOL类型
- BIT类型
- 小数类型(重点FLOAT、DECIMAL)
- 文本、二进制类型
- CHAR类型
- VARCHAR类型
- CHAR和VARCHAR的区别
- 日期时间类型
- DATE类型
- DATETIME类型
- TIMESTAMP类型
- String类型
- ENUM类型
- SET类型
- ENUM和SET的查找
mysql数据类型的认识与掌握
我们现在已经会在mysql中进行建库和建表了:
但是,对于建表而言:其中数据类型是一个很重要的部分!因为数据是有类型的!
所以,本篇文章将基于mysql中的数据类型做一个认识并掌握!
Tips:
数据类型分为很多类,就像我们在编程语言中学习的那样,一类数据类型中又被分为多种:
如整形类型:char、short、 int、 long、 long long
大部分的使用还是一样的,只不过是表示的数据范围不一样!
所以,后续的讲解中,将只会挑选一些比较常用、典型的进行讲解,其余的自行实验!
总体认识数据的分类
首先,我们先来看在mysql中,数据类型是如何分类的:
总体来说,就是上述的几种类型,我们后序将依次讲解!
数值类型
在讲解数值类型之前,先输出一个结论:
在mysql中,数值类型是可以有符号,也可以无符号的!而默认是有符号的!
TINYINT类型及其余整数类型
首先,我们来看第一个类型:TINYINT
很明显,TINYINT的范围是 -127 ~ 128
TINYINT UNSIGNED的范围是0 ~ 255
👉也就是占用两个字节!
我们这里创建一个表:
我们来试着插入一些数据(类型范围内的数据
):
如果插入一些范围之外的数据呢?
我们可以发现,mysql下:当数据越界的时候,是直接报错的!不允许插入越界数据。
我们换成无符号的整数类型试试:
注意:需要先使用
DELETE FROM table_name where ..
语句:
先把超出数据范围的数据先给删除了,如128!
然后,我们试着插入几个数据:
至此,我们就成功地证明了上述的所说的:
mysql中:数值类型一旦越界,是不允许插入的!
其实这是非常合理的:
因为数据库是需要保证数据地准确性的!
正是因为插入不合法数据mysql会进行拦截,所以数据库能够保证其内部数据的合法性!
这本质上就是一种约束:(约束也是mysql中一个很重要的话题,后序会讲):
数据类型本质上也就是一种约束,倒逼程序员做合法的插入操作!
若是不懂数据库的人,直接进行拦截即可! -> 保障数据库的安全!
其余整形类型:
类型 | 存储大小 | 有符号范围 | 无符号范围 | 描述 |
---|---|---|---|---|
TINYINT | 1 字节 | -128 到 127 | 0 到 255 | 非常小的整数 |
SMALLINT | 2 字节 | -32,768 到 32,767 | 0 到 65,535 | 小整数 |
MEDIUMINT | 3 字节 | -8,388,608 到 8,388,607 | 0 到 16,777,215 | 中等大小整数 |
INT | 4 字节 | -2,147,483,648 到 2,147,483,647 | 0 到 4,294,967,295 | 标准整数 |
BIGINT | 8 字节 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | 0 到 18,446,744,073,709,551,615 | 大整数 |
用法都是和TINYINT类似的,只要掌握了TINYINT,其余的掌握也是不在话下!
BOOL类型
BOOL类型的值只有0和1,很明显是用来表示真假的一个变量。
一般这种类型的变量可以用于记录一些只可能有两种状态的数据:
比如是否为vip、是否打开、关闭等…
我们简单测试一下即可:
先建立一个表:记录用户是否为vip,以及用户id:
插入一些数据进行测试:
要是想要筛选出是vip的用户,就很简单了(使用WHERE进行筛选):
BOOL变量是比较简单的,这里不再赘述!
BIT类型
BIT类型也是一个比较重要的类型,我们一起来看一下!
bit[(M)] : 位字段类型。M表示每个值的位数,范围从1到64。如果M被忽略,默认为1。
解释:其实这就是一个位图,它的大小是可以从1bit~64bit的!
如果不手动添加长度,默认就是1,只能表示0和1。
但是,BIT(1)和BOOL是一样的吗?
答案是不一样的,但是我们需要通过几个例子来引入不一样的地方!
先创建一个表:
我们知道,现在的bit变量是3位的,理论上能插入的值应该是 0 ~ 7:
注意:
在早期的mysql中,BIT类型是以ASCII码展示的!(如MYSQL 5.0)
但我的是MYSQL 8.0,已经是使用16进制的数来显示了。
比如我把位图改大一点,然后直接插入'a'
,发现显示的是0x61
,对应十进制的97。
所以,当类型为bit(1) || bit的时候,和bool是一样的吗?
可以说是一样,因为只能表示0和1。但是,在早期的版本下,一定是不一样的:
因为早期的版本,bit类型显示是以ASCII码显示,0和1对应的字符是不可显的!当然不一样!
小数类型(重点FLOAT、DECIMAL)
既然有整数,必然也会有小数,我们来看看小数部分和我们在语言中学的有什么不同。
FLOAT:
float[(m, d)] [unsigned] : M指定显示长度,d指定小数位数,占用空间4个字节
这里必须要明确的是:和我们在c/c++中学的肯定是不一样的!
这里声明类型的时候,m表示的是显示的长度:也就是整数部分 + 小数部分一共多少位。
d表示的是小数部分的位数!
比如:float(4, 2):
表示的是小数有4位,小数部分占两位:
有符号的情况下:范围是-99.99 ~ 99.99
无符号的情况下:范围是0 ~ 99.99
从上述的建表和实验我们可以知道:
1.小数的类型,越界也是会被拦截的!
2.输入的是整数,但是mysql会自动补齐小数位!
但是,小数部分是有一个特殊细节的:
如果说:插入的数据的小数部分比指定的小数位多,mysql会选择四舍五入!(只看d+1位置)
但是,也不是无脑的同意四舍五入的!如果五入后发现越界了,也会被拦截!
所以,小数部分:
1.输入整数/不足小数位,会自动补齐,直到小数位为指定位数
2.小数位超出指定位数,会在指定位数下一位来看是否需要四舍五入,若进位后越界也会插入失败
但是对于float而言,还有一个值得说的是:
默认情况下,不指定float,或者哪怕指定了较大的m或者d:
float是可以存储一些比较大的数字的!但是我们发现,精度丢失很严重!
其实这是可以理解的,因为存储小数遵循的标准我们在c语言那里学过,是比较复杂的!
所以,当我们想使用精度较高的浮点数,就可以使用DECIMAL:
decimal默认是10位整数,0位小数:
我们修改一下,做个实验:
我们可以发现,使用decimal的精度是非常高的!
decimal其实和float使用没有区别,区别就在于二者的精度差异!
当需要使用高精度的时候,使用decimal!
最后还剩下DOUBLE类型,这里也不再赘述了!相比于float更大,占用8字节!
文本、二进制类型
CHAR类型
char(L): 固定长度字符串,L是可以存储的长度,单位为字符,最大长度值可以为255
这里不要理解为我们在c/c++语言内学的char类型。
这里的char,实际上是一个字符串!
我们尝试着插入一些数据:
这里有一个很奇怪的现象:
按照我设置的默认的字符集utf8mb4来说,一个字符是四个字节的:
当我使用char(3)的时候,却能够存储12个字节的数据!
我们需要紧抓char类型数据的定义:
char(L):这个L不是单纯的字节数,是字符个数,这个字符,就是单纯的一个字!
这个字符个数,是不管何种字符集的。就是指定个数的字符!
VARCHAR类型
在字符类型中,还有一个叫做VARCHAR的:
varchar(L): 可变长度字符串,L表示字符长度,最大长度65535个字节
我们也是插入几个数据试试看:
也是一样的,当插入数据长度超过了指定长度,也是会被mysql进行拦截的!
注意VARCHAR的长度上限:
VARCHAR的上限是65535个字节!特别注意:是字节数,不是字符数!
我默认设置的字符集utf8mb4:一个字符四个字节:4 * 16383 = 65532Byte
所以,这就是为什么上限长度是16383了!
但是,最大字节数不是65535吗?还有三个字节呢?
这个我们放在下一个话题来解释!这涉及到CHAR和VARCHAR的区别。
CHAR和VARCHAR的区别
既然二者都是表示字符串类型的,而且从表层使用上来看没有什么区别。
但是,既然存在就有其道理,它们真正的区别是什么呢?、
先输出结论:
CHAR和VARCHAR的区别就在于:前者是定长空间,后者是变长空间!
比如:char(6) 和 varchar(6),假设我们插入'hhhh'
字符:
前者是定长空间,无论是否使用完,都要开辟6个字符的空间!就像是数组。
后者是变长空间,长度为4,还需要一个字节来记录长度,所以实际使用是5个字节!
下面这一张图可以更清晰的解释二者区别:
所以,对于VARCHAR而言,它会根据实际上存储的数据长度,来动态的使用1 ~ 3个字节来进行存储有效数据长度!所以这就是为什么,varchar的上限字节数是65532!
所以,当字符串长度是比较稳定的情况下,我们使用char即可!
若是长度变动幅度较大,更加推荐使用varchar!
日期时间类型
接下来我们来看看在mysql中,日期时间也是能作为一种数据类型而存在的!
DATE类型
date :日期 'yyyy-mm-dd' ,占用三字节
我们尝试插入几个数据:
总结几点:
1.日期类型的变量,其实也是要以字符串的形式插入,需要加单引号!
2.日期的格式就是yyyy-mm-dd
,不足的会自动补齐!
DATE是常用于记录一个特定日期的!
DATETIME类型
DATETIME其实就是在DATE的基础上,多了一个时间:
datetime 时间日期格式 'yyyy-mm-dd HH:ii:ss' 表示范围从 1000 到 9999 ,占用八字节
还是一样的,也是需要以字符串形式插入,并且:不足位会自动补齐!
这个常用于记录一下精确时间!比如火箭卫星的发射时间!
TIMESTAMP类型
TIMESTAMP是一个时间戳类型:
timestamp :
时间戳,从1970年开始的 yyyy-mm-dd HH:ii:ss 格式和 datetime 完全一致,占用四字节
在早期的mysql中,我们不需要手动地插入:(如下所示)
insert into t7(birthday, start) values('1997-7-1','2008-8-8 12:1:1')
但是,在mysql 8.0下,这个默认行为没了:
我们需要手动地插入CURRENT_TIMESTAMP
:
旧版本下,更新数据时间戳自动更新:
但是新版本需要这样做:
`ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
我们需要手动设置时间戳列的配置选项!
注意:这个配置必须保证表内该字段不能有NULL值!
添加数据自动带上当前时间戳:
修改数据,默认修改时间戳:
所以,这里需要特别注意下!
String类型
最后我们来看一下String类型的数据
ENUM类型
其实我们在c/c++那里肯定是学过这个类型的,这里的用法也是比较类似:
enum:枚举,“单选”类型;
enum('选项1','选项2','选项3',...);
注意,这里只能是多个里面选一个值进行插入:
我们在语言中学enum类型的时候:是可以通过整数来进行插入的!
(默认第一个为0,后序依次增大!也可以自定义值)
如下图所示,确实可以用数字进行插入:
只不过是:数字是从1开始计数的!有多少个枚举变量,编号最大就是多少!
说明:不建议在添加枚举值,集合值的时候采用数字的方式,因为不利于阅读。
SET类型
enum是多个选一个,但如果我们想要多个里面选多个呢?
set:集合,“多选”类型;
set('选项值1','选项值2','选项值3', ...);
相比于enum,这个可以插入多个值
(注意,是一对单引号包含多个值,而不是多对单引号!):
而且需要注意:插入多个值的时候,中间不能有空格!否则会报错!
enum能用数字来进行插入,set其实也可以:
但是我们发现,使用数字的时候看着有些奇怪,所以我们需要知道数字在set的含义!
其实,set我们可以把它看成是一个位图:
按照声明选项的顺序,从左往右就是低位到高位!
'篮球','足球','羽毛球','乒乓球','排球'
0 -> 00000 表示空
1 -> 00001 只有篮球
2 -> 00010 只有足球
3 -> 00011 篮球和足球
…
所以,只要我们搞清楚了数字的含义,使用数字进行插入就是很简单的事情了!
注意,set是允许0值的,代表什么也没有,这个和NULL还是不一样的!
NULL表示的是这一项为空
0值表示是有这一项,但是在众多选项中没有进行选择!
ENUM和SET的查找
enum的查找其实很简单,我这里不再过多赘述(直接用where指定即可!)
真正要说的是SET的查找,假设有下面这样一张表:
我们今天想要筛选出:爱好里面有篮球的人:
但是很不幸,对于WHERE来说,它是对表格进行严格筛选的:
所以,我们想要的效果就达不到了(只要爱好里面有篮球就要筛选出来)!
所以,下面需要介绍一个mysql内的函数——集合查询使用find_ in_ set
函数:
find_in_set(sub, str_list) :
如果 sub 在 str_list 中,则返回下标;如果不在,返回0;str_list 用逗号分隔的字符串。
sub是要找的子串,str_list要被搜索的字符串!
简单使用:
返回值大于0为真,表示存在(其实也就是在搜索串中的位置),反之为假,表示不存在!
现在,我们来使用该函数进行需求实现:
注意,当需要搜索多个条件的时候,不能直接在sub内输入多个选项:
如果需要的话,可以使用and或者or来进行筛选:
其实就是我们所学的条件与和条件或
!