文章目录
- MySQL数据类型
- 1. 数据类型分类
- 2. 数值类型
- 2.1 tinyint类型
- 2.2 bit类型
- 2.3 小数类型
- 2.3.1 float
- 2.3.2 decimal
- 2.4 字符串类型
- 2.4.1 char
- 2.4.2 varchar
- 2.4.3 char和varchar比较
- 2.5 日期和时间类型
- 2.6 enum和set
MySQL数据类型
1. 数据类型分类
红色标注是我主要讲解的内容
2. 数值类型
2.1 tinyint类型
tinyint有符号数据范围测试:
首先创建一个数据库,进入
进入后,创建一张表,表当中包含一个tinyint类型的列,默认其为有符号类型
注意: 在MySQL表中建立属性列,列名称在前,属性在后
列名称, 属性
由于tinyin
t的取值范围是-128~127
, 边界和范围内的数据可以插入
在此范围之外的数据无法插入
说明:
- 在MySQL中,整型可以指定是有符号的和无符号的,默认是有符号的。
- 可以通过UNSIGNED来说明某个字段是无符号的
tinyint无符号数据范围测试:
创建t2表,并且指定为无符号类型
无符号tinyint范围是0~255
,一旦越界则无法插入
注意:
-
我们平时在语言上赋值超过范围时(比如 char a =1234567),可能会发生截断后赋值,但是我们向MySQL特定的类型中插入不合法的数据,MySQL一般都是直接拦截我们,不让我们做对应的操作!
-
反过来,如果MySQL我们已经有数据被成功插入到MySQL中了,一定在插入的时候是合法的!
-
所以,MySQL中,一般而言,数据类型本身也是一种:约束
-
这样做的目的是: 倒逼程序员,让程序员尽可能进行正确的插入,约束的是: 使用者,另外若果你不是一个很好的使用者,MySQL也能保证数据插入的合法性;进而就能数据库中的数据是可预期,完整的
2.2 bit类型
基本语法
bit[(M)] : 位字段类型。M表示每个值的位数,范围从1到64。如果M被忽略,默认为1。
先创建一张表,表当中包含一个int类型和bit类型的列
bit是一种位类型,一个bit位只允许插入0或1,并且超过位数的值是无法插入的
直接查看发现是不显示的,因为bit类型在显示时,是按照ASCII
码对应的值进行显示的,有些字符是不可显示的
强转成16进制显示
修改表,改成 bit(10)
向表中插入’a’和97,最后显示都是’a’,再次验证了是按ASCII
码对应的值进行存储
bit(M),如果超过M最大值64,创建表就会失败
直接创建表,不指定bit中M的长度,默认值是1
2.3 小数类型
2.3.1 float
语法:
float[(m, d)] [unsigned] : M指定显示长度,d指定小数位数,占用空间4个字节
创建一个表,包含一个float(4,2)类型的列,默认其为有符号类型
float(4,2)表示的范围是-99.99 ~ 99.99
,在该范围内可以插入数据,超过范围报错
尝试插入一些,超过小数位数的值,下面会成功插入,因为这些四舍五入后会变成99.99
而这些无法插入,因为四舍五入后会变成100.00超过了范围
说明:MySQL在插入值时会进行四舍五入
创建一个无符号的表,还是一样的列属性
向其中中插入一些数据,发现负数和超过范围的数据是无法插入的
说明: 无符号类型的float取值范围是0~99.99
还有一个问题要注意,float类型会精度丢失问题
2.3.2 decimal
语法:
decimal(m, d) [unsigned] : 定点数m指定长度,d表示小数点的位数
- decimal(5,2) 表示的范围是 -999.99 ~ 999.99
- decimal(5,2) unsigned 表示的范围 0 ~ 999.99
- decimal和float很像,但是有区别: float和decimal表示的精度不一样
创建表,两个列类型分别是 float 和 decimal,长度和小数点位数都相同,向两列中插入同样高精度的值,float则会存在一定的精度损失,decimal则没有
说明:float表示的精度大约是7位。
- decimal整数最大位数m为65。支持小数最大位数d是30。如果d被省略,默认为0.如果m被省略,默认是10。
建议:如果希望小数的精度高,推荐使用decimal。
2.4 字符串类型
2.4.1 char
语法:
char(L): 固定长度字符串,L是可以存储的长度,单位为字符,最大长度值可以为255
-
L代表一个字符,在MySQL里一个汉字也是一个字符
-
在不同编码中,一个字符所占的字节个数是不同的,比如utf8中一个字符占3个字节,而gbk中一个字符占2个字节
先创建一张表
向其中插入一些字符,一旦字符数超过固定的长度则不会插入
也可插入汉字
2.4.2 varchar
varchar(L): 可变长度字符串,L表示字符长度,最大长度65535个字节
L代表字节
先创建表
插入数据,varchar在这与char没什么区别
说明:
关于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字节)。
2.4.3 char和varchar比较
如何选择定长或变长字符串?
- 如果数据确定长度都一样,就使用定长(char),比如:身份证,手机号,md5
- 如果数据长度有变化,就使用变长(varchar), 比如:名字,地址,但是你要保证最长的能存的进去。
- 定长的磁盘空间比较浪费,但是效率高。
- 变长的磁盘空间比较节省,但是效率低。
- 定长的意义是,直接开辟好对应的空间
- 变长的意义是,在不超过自定义范围的情况下,用多少,开辟多少
2.5 日期和时间类型
常用的日期有如下三个:
date
:日期’yyyy-mm-dd
’ ,占用三字节datetime
时间日期格式 ‘yyyy-mm-dd HH:ii:ss
’ 表示范围从1000
到9999
,占用八字节timestamp
:时间戳,从1970年开始的yyyy-mm-dd HH:ii:ss
格式和datetime
完全一致,占用四字节
先创建一张包含着3个类型的数据表
查看表的具体属性
如果向表中插入数据,t3会自动更新到最新时间(无需手动插入)
修改一下t1的时间,同时发现t3时间也更新了
那么t3这种字段究竟有什么用呢?
假设一种场景,现在有一个论坛,大家在里评论,t3会记录某人最新评论的时间
我们创建这样一个表,两列属性分别代表用户的评论内容和评论时间
现在我发表了评论,t3记录了我当前的时间
过了一会,我又重新发表了评论,则t3会更新,记录我最新发表评论的时间
2.6 enum和set
语法:
- enum:枚举,“单选”类型;
enum('选项1','选项2','选项3',...);
该设定只是提供了若干个选项的值,最终一个单元格中,实际只存储了其中一个值;而且出于效率考虑,这些值实际存储的是“数字”,因为这些选项的每个选项值依次对应如下数字:1,2,3,…最多65535个;当我们添加枚举值时也 可以添加对应的数字编号。
- set:集合,“多选”类型;
set('选项值1','选项值2','选项值3', ...);
该设定只是提供了若干个选项的值,最终一个单元格中,设计可存储了其中任意多个值;而且出于效率考虑,这些值实际存储的是“数字”,因为这些选项的每个选项值依次对应如下数字:1,2,4,8,16,32,…最多64个。
说明:不建议在添加枚举值,集合值的时候采用数字的方式,因为不利于阅读。
创建表,分别设置列数据类型为enum和set
以选择属性的形式插入性别和爱好,在范围内可成功插入
以数字的形式插入性别,枚举是从1开始的,则1代表’男’, 2代表’女’, 在这两个之外的数无法插入
以选择属性的形式插入爱好,在范围内可成功插入,如有多组值可逗号隔开插入
如果只插入username这一个,则其他两个默认为NULL
set是一个位图结构,比特位的0/1代表有无,比如上面hobby中的选项就可以这样表示
hobby选项插入为0则代表空串,插入1就是将代码的比特位置1
将上面hobby选项全部置为1则为数字31,则插入31就代表插入所有选项
集合查询使用find_ in_ set函数:
find_in_set(sub,str_list)
:如果 sub 在 str_list 中,则返回下标;如果不在,返回0;str_list
字符串是用逗号分隔的字符串
直接去筛选发现是一种精确匹配,会将属性只为羽毛球的显示
使用find_ in_ set函数,会将属性有羽毛球的显示
筛选出属性有羽毛球和代码的