【MySQL系列】深入学习数据类型

「前言」文章内容大致是数据库的数据类型。

「归属专栏」MySQL

「主页链接」个人主页

「笔者」枫叶先生(fy)

【MySQL系列】深入学习数据类型_第1张图片

目录

  • 一、数据类型分类
  • 二、数值类型
    • 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

一、数据类型分类

C/C++语言有自己的数据类型,MySQL也有自己的数据类型,常见的的数据类型如下:
【MySQL系列】深入学习数据类型_第2张图片
注:带红色的是下面要讲解的类型

数据类型的作用:

  • 决定了存储数据时应该开辟的空间大小。
  • 决定了数据的取值范围。

二、数值类型

2.1 tinyint类型

接下来讲解数值类型的整型,整型的取值范围跟C/C++语言的数据类型取值范围都差不多,同样有有符号和无符号的区别
【MySQL系列】深入学习数据类型_第3张图片

整型以tinyint为例

创建一个表,表当中包含一个tinyint类型的列,默认其为有符号类型
【MySQL系列】深入学习数据类型_第4张图片
圆括号4,下一个篇章约束再谈,这里暂时不理会
【MySQL系列】深入学习数据类型_第5张图片
tinyint类型占用1字节,有符号tinyint的取值范围为-128~127,进行插入数据
【MySQL系列】深入学习数据类型_第6张图片
如果插入的数据不在-128~127范围,则不允许插入,报错:
【MySQL系列】深入学习数据类型_第7张图片

下面是无符号tinyint范围测试

创建一个表,表当中包含一个tinyint类型的列,并指定其为无符号类型
【MySQL系列】深入学习数据类型_第8张图片
tinyint类型占用1字节,无符号tinyint的取值范围为0~255,进行插入数据:
【MySQL系列】深入学习数据类型_第9张图片
如果插入的数据不在0~255范围,则不允许插入,报错:
【MySQL系列】深入学习数据类型_第10张图片
注意:向MySQL插入不合法的数据,MySQL会直接拦截我们的操作;如果我们已经将数据成功插入表中,那么插入的数据一定合法的。所以在MySQL中,数据类型本身就是一种约束。

从上面的例子也可以看出,MySQL表中建立属性列是列名字在前,类型在后

num(列名) tinyint(类型)

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

以上便是tinyint的介绍,其他整型也类似,不再演示

2.2 bit类型

基本语法:

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

注:[] 的部分可以省略

创建一个表,表当中包含一个int类型和一个bit类型,bit默认为1位
【MySQL系列】深入学习数据类型_第11张图片
向表中插入数据,一个bit位只允许插入0,1
【MySQL系列】深入学习数据类型_第12张图片
查看表的数据,发现bit类型不显示,根本原因是因为bit类型在显示时,是按照ASCII码对应的值进行显示的,有些字符是不可显示的
【MySQL系列】深入学习数据类型_第13张图片
如果要查看该值,强转为十进制
【MySQL系列】深入学习数据类型_第14张图片
修改表,改成 bit(10)
【MySQL系列】深入学习数据类型_第15张图片
再次插入数据,结果证明确实是按ASCII码对应的值进行存储
【MySQL系列】深入学习数据类型_第16张图片
bit(M),M最大值是64,如果超过了创建表就会失败
【MySQL系列】深入学习数据类型_第17张图片
如果我们有这样的需求,只存放0或1,这时可以定义bit(1),这样可以节省空间

2.3 小数类型

2.3.1 float类型

语法:

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

创建一个表,包含一个float(4,2)类型的列,默认其为有符号类型
【MySQL系列】深入学习数据类型_第18张图片
float(4,2)表示的范围是-99.99 ~ 99.99,在该范围内可以插入数据,超过范围报错
【MySQL系列】深入学习数据类型_第19张图片
尝试插入超过范围的
说明:MySQL在保存值时会进行四舍五入
【MySQL系列】深入学习数据类型_第20张图片
即使输入多位小数,也会按指定的格式显示
【MySQL系列】深入学习数据类型_第21张图片
注意:无符号float类型的取值范围,实际就是把对应有符号float类型中的负数部分砍掉了,因此float(4,2)的取值范围为0~99.99

还有一个问题要注意,float类型会精度丢失问题
【MySQL系列】深入学习数据类型_第22张图片

2.3.2 decimal类型

语法:

decimal(m, d) [unsigned] : 定点数m指定长度,d表示小数点的位数
  • decimal(5,2) 表示的范围是 -999.99 ~ 999.99
  • decimal(5,2) unsigned 表示的范围 0 ~ 999.99
  • 这点与float是一样的

decimal和float很像,但是有区别:float和decimal表示的精度不一样

测试精度

创建一个表,表当中分别包含一个float(10,8)的列和一个decimal(10,8)的列
【MySQL系列】深入学习数据类型_第23张图片
向表当中插入数据,查表结果float则会存在一定的精度损失,decimal则没有
【MySQL系列】深入学习数据类型_第24张图片

  • float表示的精度大约是7位
  • decimal整数最大位数m为65。支持小数最大位数d是30。如果d被省略,默认为0.如果m被省略, 默认是10(可能会受到MySQL版本影响)

decimal的精度更准确,因此如果我们希望某个数据表示高精度,可以选择decimal

2.4 字符串类型

2.4.1 char类型

语法:

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

测试:

创建一个表,表当中包含一个char(2)列
【MySQL系列】深入学习数据类型_第25张图片
插入数据,需要注意的是,在MySQL里,这里所说的字符并不与C/C++里面的字符相同,在MySQL里一个汉字也是一个字符

在不同编码中,一个字符所占的字节个数是不同的,比如utf8中一个字符占3个字节,而gbk中一个字符占2个字节
【MySQL系列】深入学习数据类型_第26张图片

2.4.2 varchar类型

语法:

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

测试:

创建一个表,表当中包含一个varchar(2)
【MySQL系列】深入学习数据类型_第27张图片
插入数据,varchar在这与char没什么区别
【MySQL系列】深入学习数据类型_第28张图片

varchar类型注意事项

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

  • varchar长度可以指定为0到65535字节之间的值,但是有1 - 3 个字节用于记录数据大小,所以说有效字节数是65532
  • 当我们的表的编码是utf8时,varchar(n)的参数n最大值是65532/3=21844(因为 utf8 中,一个字符占用3个字节)
  • 如果编码是gbk,varchar(n)的参数n最大是65532/2=32766(因为gbk中,一个字符 占用2字节)

【MySQL系列】深入学习数据类型_第29张图片
【MySQL系列】深入学习数据类型_第30张图片

2.4.3 char和varchar比较

char和varchar比较

  • char类型可存储字符上限为255,varchar类型可存储字符上限与表的编码格式有关。
  • char(L)定义后,无论存储的字符串长度是否到达L,都会开辟用于存储L个字符的定长空间,如果存储的字符串长度超过L则会报错。
  • varchar(L)定义后,会根据存储字符串的长度按需开辟空间,并且需要使用1-3字节的空间用于表示存储字符串的长度以及其他控制信息,如果存储的字符串长度超过L则会报错。

以utf8编码为例:
【MySQL系列】深入学习数据类型_第31张图片

如何选择定长(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 完全一致,占用四字节

创建一个表,表当中包含date、datetime和timestamp三种时间日期类型的列

查看表结构可以看到,timestamp类型的t3列是不允许为空的,它的默认值为CURRENT_TIMESTAMP

如果向表中插入数据,t3会自动更新到最新时间(无需手动插入)
【MySQL系列】深入学习数据类型_第32张图片
向表中插入值
【MySQL系列】深入学习数据类型_第33张图片
更新数据,时间戳会更新
【MySQL系列】深入学习数据类型_第34张图片

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个

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

例子

创建一个调查表,表当中包含被调查人的姓名、性别(只选一个)和爱好(多个)
【MySQL系列】深入学习数据类型_第35张图片
向表中插入记录时,被调查人的性别只能从男和女中进行二选一,被调查人的爱好可以从提供的若干个选项中进行多选一或多选多,多个爱好之间需要通过英文逗号隔开
【MySQL系列】深入学习数据类型_第36张图片

可以通过数字设置enum

数字是从1开始,有几个值数字最大就是几,例如enum(‘男’, ‘女’),数字1代表男,数字2代表女,最大就是2,超过了范围则不允许插入
【MySQL系列】深入学习数据类型_第37张图片
根本原因在于,MySQL出于效率考虑,这些值(比如男,女)实际存储的是“数字”,因为这些选项的每个选项值依次对应如下数字:1,2,3,....,最多65535

可以通过数字设置set

在插入记录时,除了通过指明多个选项来设置爱好,还可以通过数字的方式来设置
使用数字插入并不是使用下标,使用的是位图的方式进行插入
例如:

'羽毛球','游泳','篮球','写代码' // 4个爱好
用比特位表示:0000
0001 (1)是羽毛球
0010 (2)是游泳
0011 (3)是羽毛球,游泳
0100 (4)是篮球
依次类推
1111 (15)则是'羽毛球','游泳','篮球','写代码'

【MySQL系列】深入学习数据类型_第38张图片
【MySQL系列】深入学习数据类型_第39张图片
【MySQL系列】深入学习数据类型_第40张图片
:虽然enum和set可以通过数字的方式进行设置,但严重不推荐这种做法,因为这样的SQL可读性太差

enum和set查找

如果想要筛选出调查表中的所有女的或男的,那么直接在筛选时指明gender='女'或者gender='男'即可
【MySQL系列】深入学习数据类型_第41张图片
但如果要筛选出调查表中爱好包含游泳的就不能使用where了,这并不是我们想要的结果
【MySQL系列】深入学习数据类型_第42张图片

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

  • find_in_set(sub,str_list) :如果 sub 在 str_list 中,则返回下标;如果不在,返回0;
  • str_list字符串是用逗号分隔的字符串

【MySQL系列】深入学习数据类型_第43张图片
--------------------- END ----------------------

「 作者 」 枫叶先生
「 更新 」 2023.7.17
「 声明 」 余之才疏学浅,故所撰文疏漏难免,
          或有谬误或不准确之处,敬请读者批评指正。

你可能感兴趣的:(MySQL,mysql,学习,android)