MySQL —— 数据类型

目录

一、数据类型的分类

二、数值类型

1. tinyint类型

2. bit类型

3. float类型

4. decimal类型

三、字符串类型

1. char类型

2. varchar类型

3. char和varchar的比较

四、时间日期类型

五、enum和set类型 


一、数据类型的分类

分类 数据类型 说明
数值类型 BIT(M) 位类型:M指定位数,默认值为1,范围为1-64
BOOL 布尔类型:使用1表示真,使用0表示假
TINYINT [UNSIGNED] 占用1字节,默认为有符号
SMALLINT [UNSIGNED] 占用2字节,默认为有符号
MEDIUMINT [UNSIGNED] 占用3字节,默认为有符号
INT [UNSIGNED] 占用4字节,默认为有符号
BIGINT [UNSIGNED] 占用8字节,默认为有符号
FLOAT[(M,D)] [UNSIGNED] M指定显示长度,D指定小数位数,占用4字节
DOUBLE[(M,D)] [UNSIGNED] M指定显示长度,D指定小数位数,占用8字节
DECIMAL(M,D) [UNSIGNED] M指定显示长度,D指定小数位数,每4个字节表示9个数字,小数点占用1字节
文本、二进制类型 CHAR(L) 固定长度字符串:L指定字符串长度,最大为255
VARCHAR(L) 可变长度字符串:L指定字符串长度上限,最多占用65535字节
BLOB 用于存储二进制数据
TEXT 用于存储大文本数据
时间日期 DATE / DATETIME 日期类型:YYYY-MM-DD格式 / YYYY-MM-DD HH:MM:SS格式
TIMESTAMP 时间戳:以YYYY-MM-DD HH:MM:SS格式进行显示
字符串类型 ENUM 枚举类型:ENUM类型的取值范围需要在定义字段时进行指定,设置字段值时只允许从成员中选取单个值,其所需的存储空间由定义ENUM类型时指定的成员个数决定
SET 集合类型:SET类型的取值范围需要在定义字段时进行指定,设置字段值时可以从成员中选取一个或多个值,其所需的存储空间由定义SET类型时指定的成员个数决定

二、数值类型

1. tinyint类型

有符号的tinyint测试(默认是有符号的,范围是-128~127) ,我们先创建一个t1表向其中插入数据,看看效果:

无符号的tinyint测试(默认是有符号的,范围是0~255) ,我们创建一个t2表向其中插入数据,看看效果:

        从上面的测试效果来看,MySQL的数据类型起到了一种约束的作用,这也是我们后面将要学习的内容,这里就大概了解约束的概念,你选择的类型就约束了你必须执行正确的SQL语句;

2. bit类型

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

创建一个t3表,表当中包含一个int类型的id列和一个8位bit类型的a列。向表中插入一条记录,记录中指定id和a的值均为10,插入记录后查看表会发现a的值显示的并不是10。如下:

        根本原因是因为bit类型在显示时,是按照ASCII码对应的值进行显示的,而在ASCII码表中10对应的是控制字符LF,表示换行的意思。如果向表中插入记录时指定id和a的值均为65,由于ASCII码表中65对应的是字符A,因此插入记录后查看表就会发现a的值显示的是A。如下:

bit类型的范围测试

如果我们有这样的值,只存放0或1,这时可以定义bit(1)。这样可以节省空间。

        在我们创建的t4表中,有一个gender列,它是表示性别的,要么是男要么是女,此时1个比特位就刚好表示男或女,节省了空间;我们也可以发现,当你插入0/1时是可以的,但是插入2/3是不可以的,因为2/3不可能用1个比特位来表示;

3. float类型

有符号的float范围测试:

        MySQL在保存值时会进行四舍五入,因此实际可插入float(4,2)的范围为-99.994~99.994,如果插入的数据不在该范围内,那么插入数据时就会产生报错。 

 无有符号的float范围测试:

如果插入的数据不在0~99.994范围内,那么插入数据时就会产生报错。 

        通过上面的t6表和下面这个t7表,我相信你应该能更清楚的知道float后面括号内的数字的具体含义了(也就是所表示的范围);

4. decimal类型

decimal(m, d) [unsigned] : 定点数m指定长度,d表示小数点的位数

decimal和float类型的使用方式一样,但decimal的精度比float更高。

创建一个表,表当中分别包含一个float(10,8)的列和一个decimal(10,8)的列。如下:

        向表当中插入一条记录,指定float和decimal的值均为3.141592653,但最终查表时会发现decimal基本保持了数据的原貌,而float则会存在一定的精度损失。如下:

三、字符串类型

1. char类型

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

创建一个表,表当中包含一个char(2)的name列。如下: 

        注意:这里的2表示能够存储的字符个数为2。因此只要插入的字符个数不超过2个都是能够成功插入的(汉字也是可以的),如果插入的字符个数超过了6个,那么在插入数据时就会产生报错。如下:

         在不同编码中,一个字符所占的字节个数是不同的,比如utf8中一个字符占3个字节,而gbk中一个字符占2个字节。MySQL限定字符的概念不是字节,这样用户就不用关心复杂的编码细节了。

2. varchar类型

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

创建一个表,表当中包含一个id列和一个varchar(6)的name列。如下: 

由于varchar(6)中最多可存储6个字符,因此只要插入的字符个数不超过6都是能够成功插入的。如下:

如果插入的字符个数超过了6个,那么在插入数据时就会产生报错。如下:

varchar类型可指定的字符个数上限

varchar类型最多占用65535字节,其中有1~2字节用来表示实际数据长度,还有1字节来存储其他控制信息,因此varchar类型的有效字节数最多是65532字节。

而varchar类型可指定的字符个数上限,与表的编码格式有关:

对于utf8编码来说,一个字符占用三个字节,因此varchar(L)中的L最大可指定为

65532 ÷ 3 = 21844            


对于gbk编码来说,一个字符占用两个字节,因此varchar(L)中的L最大可指定为

65532 ÷ 2 = 32766          

因此在定义编码格式为utf8的表时,varchar(L)中的L如果超过了21844,则会产生报错。如下: 

而在定义编码格式为gbk的表时,varchar(L)中的L如果超过了32766,则会产生报错。如下:

3. char和varchar的比较

char和varchar的区别如下:

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

如何选取char和varchar类型?

char和varchar的优缺点如下:

  • char类型的数据是定长的,因此磁盘空间比较浪费,但是效率高。
  • varchar类型的数据是变长的,因此磁盘空间比较节省,但是效率低(需要先读取存储字符串的长度,再访问指定长度的空间)。

        如果要存储的数据是定长的,那就使用char类型进行存储,比如身份证号码、手机号、md5等。如果要存储的数据是变长的,那就使用varchar类型进行存储,比如名字、地址等。

四、时间日期类型

常用的日期有如下三个:  

  • 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列,那么就会自动插入当前的时间戳。如下:

timestamp类型使用案例:微波/CSDN的评论

创建一个评论表,表当中包含评论人的昵称、评论的内容和评论的发布时间。如下:

五、enum和set类型 

enum和set类型的区别如下:

  • 在定义enum字段时需要提供若干个选项的值,在设置enum字段值时只允许选取其中的一个值
  • 在定义set字段时需要提供若干个选项的值,在设置set字段值时可以选取其中的一个或多个值

        比如人的性别只能从男和女中进行二选一,因此可以定义成enum类型,而人的爱好在提供的选项中可能存在多个,因此可以定义成set类型。

使用案例:调查表

创建一个调查表,表当中包含被调查人的姓名、性别和爱好。如下: 

向表中插入记录时,被调查人的性别只能从男和女中进行二选一,被调查人的爱好可以从提供的若干个选项中进行多选一或多选多,多个爱好之间需要通过英文逗号隔开。如下:

通过数字设置enum

在插入记录时,除了通过指明男女来设置性别,还可以通过插入数字1和2来设置性别。如下: 

根本原因在于,MySQL出于效率考虑,在存储enum值时实际存储的都是数字,enum中提供的选项值依次对应数字1、2、3、…,最多65535个,因此在设置enum值时可以通过数字的方式进行设置。

通过数字设置set

在插入记录时,除了通过指明多个选项来设置爱好,还可以通过数字的方式来设置。如下:

 MySQL存储set值时实际存储的也是数字,set中提供的选项值依次对应数字1、2、4、8、…,最多64个,因此在设置set值时可以通过数字的方式进行设置。你设置了几个爱好就有几个比特位,你所给定的数字都需转化为相应的二进制位,哪些比特位是1,就对应着哪个爱好;

建议:

  • 虽然enum和set可以通过数字的方式进行设置,但严重不推荐这种做法,因为这样的SQL可读性太差,导致后期维护成本变高。

enum和set查找 

如果想要筛选出调查表中所有女同志的信息,那么直接在筛选时指明gender = '女'即可,因为enum类型的值只能多选一。如下:

但如果要筛选出调查表中爱好包含打羽毛球的人的信息就比较麻烦了,如果继续使用上述方式,那么最终筛选出来的是爱好仅为敲代码的人的信息。如下:

这时需要借助find_in_set(str,strlist)函数,该函数的作用是查询strlist中是否包含str,如果包含则返回str在strlist中的位置(从1开始),否则返回0。

对于查找,我们在后面的博客中会有介绍 

猜你喜欢

转载自blog.csdn.net/sjsjnsjnn/article/details/128762859