【MySQL 05】数据类型

🌈 一、数据类型的作用

  • 如果向 MySQL 特定的类型中插入不合法的数据,MySQL 一般会将本次操作直接拦截。反过来讲,能被成功插入到 MySQL 中的数据一定合法。
  • 在 MySQL 中,数据类型本身也是一种约束,这种约束约束的是使用者,让程序员尽可能正确的进行插入。

🌈 二、常见数据类型分类

  1. 数值类型
数据类型大小说明
BIT(M)1 ~ 64 比特位类型,用 M 指定位数,默认值位 1,范围 1 ~ 64。
TINYINT [UNSIGNED]1 字节范围:有符号(-128 ~ 127);无符号(0 ~ 255);默认为有符号
BOOL1 字节布尔类型,1 表示真,0 表示假
SMALLINT [UNSIGNED]2 字节范围: 有符号(-215,215-1);无符号(0,216-1);默认为有符号
INT [UNSIGNED]4 字节范围: 有符号(-231,231-1);无符号(0,232-1);默认为有符号
BIGINT [UNSIGNED]8 字节范围: 有符号(-263,263-1);无符号(0,264-1);默认为有符号
FLOAT [(M,D)] [UNSIGNED]4 字节M 指定显示长度,D 指定小数的位数
DOUBLE[(M,D)] [UNSIGNED]8 字节表示比 float 精度更大的小数
DECIMAL [(M,D)] [UNSIGNED]如果 M > D,则为 M + 2,否则为 D + 2定点数 M 指定长度,D 表示小数的位数
  1. 文本、二进制类型
数据类型大小说明
CHAR(L)0 ~ 255 字节定长字符串,L 指定字符串长度,存储的容量无法超过指定的 L
VARCHAR(L)0 ~ 65535 字节变长字符串,L 指定字符串长度,存储的容量可以超过指定的 L
BLOB0 ~ 65535 字节存储二进制数据
TEXT0 ~ 65535 字节存储大文本数据,不支持全文索引和默认值
  1. 日期和时间类型
数据类型大小格式用途
DATE3 字节YYY-MM-DD日期值
DATETIME8 字节YYYY-MM-DD hh:mm:ss混合日期和时间值
TIMESTAMP4 字节YYYY-MM-DD hh:mm:ss时间戳
  1. 字符串类型
数据类型说明
ENUM枚举类型,在定义字段时指定取值范围,字段值只允许从成员中选取单个值,其所需的存储空间由定义 ENUM 类型时指定的成员个数决定
SET集合类型,在定义字段时指定取值范围,字段时可从成员中选取一个或多个值,其所需的存储空间由定义 SET 类型时指定的成员个数决定

🌈 三、数值类型

  • 在 MySQL 中,整型可以指定是有符号的和无符号的,默认是有符号的。
  • 可以通过 UNSIGNED 来说明某个整型字段是无符号的。

⭐ 1. tinyint 类型

  • int 类型以 tinyint 为例测试类型的存储范围,其他所有 int 类型范围测试方法同理。

1. 有符号 tinyint 范围测试

  • 创建一个包含 tinyint 类型字段名为 t1 的表,默认其为有符号类型。

image-20240810093627984

  • tinyint 类型大小为 1 字节,有符号 tinyint 的取值范围为 -128 ~ 127,只要插入的数据在该范围都能成功插入。

image-20240810093522285

  • 插入数据时,如果插入的数据不在 -128 ~ 127 这个合法范围内,会直接发生报错。

image-20240810093906470

2. 无符号 tinyint 范围测试

  • 创建一个包含 tinyint 类型字段名为 t2 的表,在 tinyint 后面添加上 UNSIGNED 使其成为无符号类型。

image-20240810094144610

  • 无符号 tinyint 的取值范围为 0 ~ 255,只要插入的数据在该范围都能成功插入。

image-20240810094448611

  • 插入数据时,如果插入的数据不在 0 ~ 255 这个合法范围内,会直接发生报错。

image-20240810094609094

⭐ 2. bit 类型

  • bit 语法格式

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

1. bit 类型的显示方式

  • 创建一张名为 t3 的表,表中包含一个名为 id 类型为 int 的字段,和一个名为 a 类型为 bit(8) 的字段。

image-20240810101739152

  • 往表中的 id 字段和 a 字段各插入一个 10,数据插入之后会发现 a 字段显示出来的内容并不是 10,而是 10 对应的 16 进制值。

image-20240810103246926

2. 比特类型的使用案例

  • 创建一张名为 t4 的表,表中包含一个名为 name 类型为 varchar(20) 的字段,和一个名为 gender 类型为 bit(1) 的字段。
    • 由于 gender 性别在正常情况下只有 2 种,可以使用 1 位 bit 表示用以节省空间。

image-20240810105402980

  • 暂时将 1 定义为男,0 定义为女,在往 gender 字段插入数据时就可以用 1 位 bit 来表示男女。

image-20240810104708553

  • 如果插入 gender 字段的不是 0 / 1,MySQL 会拦截这次访问。

image-20240810105005505

⭐ 3. float 类型

  • float 语法格式

    float[(m, d)] [unsigned] : m 指定数字位数的总个数,d 指定小数点之后数字的个数,占用空间为 4 字节
    

1. 有符号 float 类型范围测试

  • 创建一张名为 t5 的表,表中包含一个名为 num,类型为 float(4,2) 的字段,默认其为有符号类型。

image-20240810111216131

  • 由于 float(4, 2) 该字段能装 4 个数字,小数点后能装 2 个数字,因此该字段的取值范围为 -99.99 ~ 99.99,只要在这个范围的数字都能成功插入。

image-20240810111637317

  • MySQL 在保存值时支持进行四舍五入,因此 float(4, 2) 字段的实际可插入范围为 -99.994 ~ 99.994,MySQL 会拦截不在该范围的数据插入操作。

image-20240810112208384

2. 无符号 float 类型范围测试

  • 创建一张名为 t6 的表,表中包含一个名为 num,类型为 float(4,2) 的字段,并在 float(4,2) 之后使用 unsigned 指定其为无符号类型。

image-20240810112913260

  • 无符号 float(4,2) 类型的取值范围并不是将 99.99 * 2 就完了,(4, 2) 已经限制了正数部分最高就只能取到 99.99,只是单纯的不让你存负数了而已。
    • 又因为 float 支持四舍五入,因此实际可插入范围为 0 ~ 99.994,不在该范围内的数据插入操作都会被 MySQL 拦截。

image-20240810113555114

⭐ 4. decimal 类型

  • 在小数点后位数很多的时候,float 类型会发生精丢失,而 decimal 是一个精度更高的浮点数类型,可以很好的解决精度丢失的问题。

  • decimal 语法格式

    decimal(m, d) [unsigned] : m 指定数字位数的总个数,d 指定小数点之后数字的个数
    

float 和 decimal 的精度对比

  • 创建一张名为 t7 的表,表中分别包含一个 float(10,8) 的字段和一个decimal(10,8) 的字段。

image-20240810120346615

  • 分别往两个字段各自插入一段 32.42342321,decimal 能够保持数据的原貌,而 float 发生了精度丢失。

image-20240810120656062

🌈 四、字符串类型

  • 在不同编码中,一个字符所占的字节个数是不同的。
    • utf8 中一个字符占3个字节,而 gbk 中一个字符占 2 个字节。
  • MySQL 限定字符的概念不是字节,而是字符个数,用户无需再关心编码细节。

⭐ 1. char 类型

  • char 类型使用格式

    char(L): 固定长度字符串,L 表示字符个数,并不代表字节数
    
  • char 类型在指定 L 之后会一次性开辟出 L 个字符的空间。

char 类型使用案例

  • 创建一张名为 t8 的表,表中包含一个名为 content,数据类型为 char(6) 的字段。

image-20240810141821217

  • 类型为 char(6) 的字段最多可以存储 6 个字符 (英文 / 汉字),只要插入字符个数不超过 6 个都能插入成功,反之则会被 MySQL 拦截。

image-20240810142222894

  • 注意:char(L) 类型的 L 最多不能超过 255。

⭐ 2. varchar 类型

  • varchar 语法格式

    varchar(L): 可变长度字符串,L 表示字符个数,并不代表字节数
    
  • varchar 允许在 L 规定的范围内灵活的开辟空间。

    • 假设 L 是 6,varchar 一开始是不开辟空间的,只有在实际插入数据时再开辟空间,但插入的字符数不能超过 6。

1. varchar 类型使用案例

  • 创建一张名为 t9 的表,表中包含一个名为 content,数据类型为 varchar(6) 的字段。

image-20240810145130066

  • varchar(6) 最多可存储 6 个字符,只要插入的字符个数在 6 个及以下,本次操作就是合法的。

image-20240810154029528

  • 如果要插入的字符个数超过了 L 所指定的 6 个字符,则本次操作会被 MySQL 拦截。

image-20240810154144535

2. varchar 类型可存储的字符个数

  • varchar 占用空间范围在 0 ~ 65535 字节,但其中有 1 ~ 3 字节用来记录数据大小,因此 varchar 类型的有效字节数最多是 65532 字节

  • 但这只是 varchar 类型的所占空间范围,L 具体最多能表示多长的字符串还要看表对应的编码格式。

    • 对于 utf8 编码格式,一个字符占 3 个字节,因此 L 能够指定的最大字符串长度为 65532 / 3 = 21844。
    • 对于 gbk 编码格式,一个字符占 2 个字节,因此 L 能够指定的最大字符串长度为 65532 / 2 = 32766。
  • 建表时,如果定义的编码格式为 utf8,且 varchar(L) 中的 L 超过了 21844,则本次操作会被 MySQL 拦截下来。

image-20240810151229535

  • 建表时,如果定义的编码格式为 gbk,且 varchar(L) 中的 L 超过了 32766,则本次操作会被 MySQL 拦截下来。

image-20240810151705256

⭐ 3. char 和 varchar 比较

实际存储char(4)varchar(4)char 所占字节varchar 所占字节
abcdabcdabcd4 * 3 = 124 * 3 + 1 = 13
AAA4 * 3 = 121 * 3 + 1 = 4
Abcde××数据超过长度数据超过长度

1. char 和 varchar 的区别

  • char 类型可存储的字符上限就是 255 个字符。而 varchar 可存储的字符上限受表的编码格式所影响。
  • char(L) 在定义好后,会一次性开辟好 L 个字符的空间。而 varchar(L) 则是在以 L 为上限的情况下,用多少开辟多少。

2. char 和 varchar 的优缺点

  • char 是定长的,因此会比较浪费磁盘空间,但是效率高 (能直接访问定长的空间)。
  • varchar 是变长的,因此会比较节省磁盘空间,但是效率低 (需要维护字符串 )。

3. 如何选择 char 还是 varchar

  • 确定数据长度的情况下,可使用定长字符串 char (如:身份证号、手机号、银行卡号等)。
  • 不确定数据长度的情况下,可使用变长字符串 varchar (如:名字、地址、籍贯等)。

🌈 五、日期和时间类型

数据类型大小格式用途
DATE3 字节YYY-MM-DD日期值
DATETIME8 字节YYYY-MM-DD hh:mm:ss混合日期和时间值
TIMESTAMP4 字节YYYY-MM-DD hh:mm:ss时间戳

1. 三种时间类型对应的表结构

  • 创建一张名为 t10 的表,表中分别包含 3 中类型为 date、datetime、timestamp 的字段。

image-20240810175919291

2. 往各类型字段插入时间数据

image-20240810180641447

🌈 六、enum 和 set 类型

⭐ 1. enum 和 set 类型的区别

  • enum 枚举 (单选) 类型:在定义 enum 字段时需要提供若干个选项的值,在设置 enum字段值时只允许选取其中的一个值。

    enum('选项1', '选项2', '选项3', ..., '选项n');
    
  • set 集合 (多选) 类型:在定义 set 字段时需要提供若干个选项的值,在设置 set 字段值时可以选取其中的一个或多个值。

    set('选项值1', '选项值2', '选项值3', ..., '选项值n');
    

⭐ 2. enum 和 set 类型的使用案例

  • 创建一张名为 votes 的问卷调查表,表中包含被调查人的姓名、喜好(登山,游泳,篮球,武术等 、性别 (男 / 女)。
    • 在大多数情况下,人的性别只有两种,因此可以定义成 enum 类型。而人的爱好在提供的选项中可能存在多个,因此可以定义成 set 类型。

image-20240810183419048

  • 往表中插入数据时,被调查人的性别只能从男 / 女中选择 1 个,被调查人的爱好可以从提供的若干个选项中选择 n 个。
    • 注意:多个爱好之间需要通过英文逗号隔开。

image-20240810184307516

⭐ 3. 通过数字设置 enum 和 set

  • MySQL 在存储 enum 值时实际存储的都是数字,enum 中提供的选项值依次对应数字1、2、3、… n 最多 65535 个,因此在设置 enum 值时可以通过数字的方式进行设置。
  • MySQL 存储 set 值时实际存储的也是数字,set 中提供的选项值依次对应数字 1、2、4、8、…,最多 64 个,在设置 set 值时也能通过数字的方式。
  • 虽然通过数字设置 enum 和 set 值很方便,但还是不推荐通过数字设置 enum 和 set 值,因为这样会导致可读性变差的情况。

1. 通过数字设置 enum

  • 在往表中插入数据时,除了能够通过男 / 女指定用户的性别,还可以通过插入数字 1 / 2来设置性别,enum 的数字表示的是下标

image-20240810184834763

2. 通过数字设置 set

  • set 是通过比特位上对应位置的 1 往表中插入数的,set 的数字表示的是位图
    • 如:1 是第一个比特位为 1,就会将第一个值 ‘踢足球’ 设置,2 是第二个比特位为 1,就会设置成第二个值 “打游戏”。
    • 如果设置的值有多个位为 1,比如说 3,就会设置第一个和第二个值 (踢足球和打游戏),其余同理。

image-20240810191657958

⭐ 4. 通过 enum 和 set 的值进行查找

  • MySQL 也支持通过 enum 和 set 中的值进行查找。

1. 通过 enum 的值进行查找

  • 如果想要找出表中所有的女性,由于 enum 的值只能单选,因此在筛选时可以直接指明 gender=‘女’ 即可。

image-20240810192832785

2. 通过 set 的值进行查找

  • 查找表中爱好包含敲代码的人,由于 set 是个集合,里面的值可以多选,如果仍然使用上面的方法查找就只能找到只有敲代码一个爱好的人。
    • 此时就要引出一个集合查询函数 find_in_set 了。

image-20240810193337629

⭐ 5. 通过 find_ in_ set 函数进行集合查询

  • find_in_set(sub, str_list):判断子集在对应列表中是否存在,如果 substr_list 中,则返回 sub 在 str_list 中对应的下标,否则返回 0。
    • 注:str_list 是一个用逗号分隔的字符串。

1. find_in_set 函数示例

  • 依次查找 a、b、d 这三个字符是否在集合 {a, b, c} 中,如果找到了则返回对应字符在集合中的下标。
    • a、b 在 {a, b, c} 集合中的下标分别为 1、2,而 d 不在该集合中,因此会返回 0。

image-20240810194417668

2. 筛选出爱好包含敲代码的人

  • 此时就可以让 select 搭配 find_in_set 函数,来筛选出所有爱好包含敲代码的人了。

image-20240810194605825

3. 筛选出爱好不仅仅只有敲代码的人

  • 要删选出爱好里面有 “敲代码”,但不止有敲代码这一个爱好的人 (没错就是要把方九剔除掉)。

image-20240810200627886

  • 52
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值