【MySQL】数据类型

在这里插入图片描述

一. 数值类型

在这里插入图片描述

1. tinyint 类型

# 连接mysql数据库
mysql -uroot -p
# 先创建数据库,再使用数据库
create database data;
use data;

有符号 tinyint 范围测试

create table t1(num tinyint);
insert into t1 values (-128); # 插入成功
insert into t1 values (127);  # 插入成功
insert into t1 values (128);  # 插入失败
select * from t1;

在这里插入图片描述

  • 在 MySQL 中,整型可以指定是有符号的和无符号的,默认是有符号的。
  • 由于 tinyint 类型占用1字节,因此有符号 tinyint 的取值范围为 -128 ~ 127,插入该范围内的数据时都能成功插入,如果插入的数据不在 -128 ~ 127范围内,那么插入数据时就会产生报错。
  • 可以通过 unsigned 来说明某个字段是无符号的。

无符号 tinyint 范围测试

create table t2(num tinyint unsigned);
insert into t2 values (0);    # 插入成功
insert into t2 values (255);  # 插入成功
insert into t2 values (-1);   # 插入失败
select * from t2;

在这里插入图片描述

  • 由于tinyint类型占用1字节,因此无符号tinyint的取值范围为 0 ~ 255,插入该范围的数据时都能成功插入,如果插入的数据不在 0 ~ 255范围内,那么插入数据时就会产生报错。
  • 其他类型也是如此,对于不同的场景选择合适的数据类型。
  • 如果我们向 MySQL 指定的类型插入不合法的数据,MySQL 一般会直接拦截我们,不让我们做对应的操作。反过来,如果我们已经有数据被成功插入到 MySQL 中,插入的数据一定是合法的。所以在 MySQL 中,数据类型本身也是一种约束,约束程序员进行正确的插入!
  • 除非场景要求数值类型必须是无符号,否则尽量不要使用无符号,因为有符号的数值类型存不下的数据,其对应的无符号类型同样可能存不下,这时应该直接将数值类型进行提升。

2. bit 类型

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

bit 类型的范围测试

创建一个表 t3,表当中包含用户值 id 和用户是否在线 online,其中 online 的类型可以指定为 1 位 bit 类型,因为性别只有两种取值,使用1个比特位来表示用户是否在线就可以节省空间,再插入一些数据,最后查看表中的数据,如下:

create table t3(
	id int,
	online bit(1)
);
insert into t3 values (111, 0); # 插入成功
insert into t3 values (222, 1); # 插入成功
insert into t3 values (333, 2); # 插入失败
select * from t3;
select id, hex(online) from t3;

在这里插入图片描述

  • 如果插入 online 列的数据不是0或1,那么插入数据时就会产生报错。
  • 默认查看到的是十六进制的数据,可以用 hex(online) 转换为十进制数据。

修改表中 online 列的属性为 bit(10),再插入数据,最后查看表中的数据。

alter table t3 modify online bit(10);
desc t3;
insert into t3 values (111, 48);
select * from t3;
select id, hex(online) from t3;

在这里插入图片描述

在这里插入图片描述

3. 浮点数类型

1. float 类型

  • float[(m, d)] [unsigned]:m数值的位数,d小数的位数,占用空间4个字节。

有符号 float 范围测试

create table t4(
	id int,
	salary float(4, 2)
);
insert into t4 (id, salary) values(1, -99.99); # 插入成功
insert into t4 (id, salary) values(1, 99.99);  # 插入成功
insert into t4 (id, salary) values(1, 88);     # 插入成功
insert into t4 (id, salary) values(1, 100.0);  # 插入失败
select * from t4;

在这里插入图片描述

insert into t4 (id, salary) values(1, 12.234); # 插入成功
insert into t4 (id, salary) values(1, 12.235); # 插入成功
insert into t4 (id, salary) values(1, 99.994); # 插入成功
insert into t4 (id, salary) values(1, 99.995); # 插入失败
select * from t4;

在这里插入图片描述

  • float(4,2) 表示有符号的数,范围是 -99.99 ~ 99.99。
  • float(4,2) unsigned 表示无符号的数,范围是 0 ~ 99.99。
  • MySQL在保存值时会进行四舍五入。
create table t5(
	id int,
    salary float
);
insert into t5 (id, salary) values (1, 123456789.123456);
insert into t5 (id, salary) values (1, 123456789123.123);
select * from t5;

在这里插入图片描述

结论:float 存储是有精度损失的!

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 表示的精度不一样。
create table t6(
    f1 float(10, 8),
    f2 decimal(10, 8)
);
insert into t6 (f1, f2) values (12.12345678, 12.12345678);
select * from t6;

在这里插入图片描述

结论:decimal的精度更准确,因此如果我们希望某个数据表示高精度,推荐使用decimal

二. 字符串类型

1. 定长 char 类型

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

char 类型测试

create table if not exists t7(
    id int,
    name char(2)
);
insert into t7 (id, name) values (1, 'a');       # 插入成功
insert into t7 (id, name) values (1, 'ab');      # 插入成功
insert into t7 (id, name) values (1, 'abc');     # 插入失败
insert into t7 (id, name) values (1, '你');      # 插入成功
insert into t7 (id, name) values (1, '你好');    # 插入成功
insert into t7 (id, name) values (1, '你好码吗');  # 插入失败
select * from t7;

在这里插入图片描述

  • char(2) 表示可以存放两个字符,可以是字母或汉字,但是不能超过2个, 最多只能是255
  • 在 gbk 编码1个汉字对应2个字节,在 utf-8 中1个汉字对应3个字节。
  • MySQL 限定字符的概念不是字节,这样用户就不用关心复杂的编码细节了。

2. 变长 varchar 类型

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

varchar 类型测试

create table t8( 
	id int, 
	name varchar(7) 
);
insert into t8 (id, name) values (1, '江山如此多娇');     # 插入成功
insert into t8 (id, name) values (1, '引无数英雄竞折腰');  # 插入失败
select * from t8;

在这里插入图片描述

关于 varchar(L) 中的 L 到底是多大,这与表的编码密切相关:

  • varchar 的字节可以指定为 0~65535 之间的值,但是有1 - 3 个字节用于记录数据大小,所以说有效字节数是65532
  • 当我们的表的编码是 utf-8 时,varchar(n) 的参数 L 最大值是 65532/3=21844 (因为 utf-8 中,一个字符占用3个字节),如果编码是 gbk,varchar(n) 的参数 L 最大是 65532/2=32766 (因为 gbk 中,一个字符占用2字节)
create table t9(
	name varchar(21845)
)charset=utf8; # 建表失败

create table t10(
	name varchar(21844)
)charset=utf8; # 建表成功

在这里插入图片描述

3. char 与 varchar 的比较

在这里插入图片描述

如何选择定长或变长字符串?

  • 如果数据长度都一样,就使用定长 char,比如:身份证,手机号。
  • 如果数据长度有变化,就使用变长 varchar,比如:名字,地址。但要保证最长的能存的进去。
  • 定长的磁盘空间比较浪费,但是效率高。
  • 变长的磁盘空间比较节省,但是效率低。
  • 定长的意义是,直接开辟好对应的空间。
  • 变长的意义是,在不超过自定义范围的情况下,用多少,开辟多少。

4. 日期和时间类型

常用的三种时间日期类型如下:

  • date:日期 'yyyy-mm-dd',占用3个字节。
  • datetime:日期时间 'yyyy-mm-dd HH:ii:ss' 表示范围从 1000 到 9999,占用8个字节。
  • timestamp:时间戳,从1970年开始的 yyyy-mm-dd HH:ii:ss 格式和 datetime 完全一致,占用4个字节。
create table t11(
    t1 date,
    t2 datetime,
    t3 timestamp
);
alter table t11 modify column t3 timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP;
desc t11;

在这里插入图片描述

# 添加数据时,时间戳更新为当前时间
insert into t11 (t1, t2) values ('2025-4-23', '1970-01-01 00:00:00'); 
select * from t11;

在这里插入图片描述

# 更新时间t1时,时间戳自动更新为当前时间
update t11 set t1='2025-4-24';
select * from t11;

在这里插入图片描述

  • date:记录日期。
  • datetime:记录日期 + 时间。
  • timestamp:程序员不需要修改,当修改表中其它字段时,时间戳自动更新为当前时间。通常用于在社交平台中评论,你当前的时间会显示出来。

timestamp 类型使用案例

create table t12(
	comment text, 
	time timestamp 
);
alter table t12 modify column time timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP;
insert into t12 (comment) values ('你好!');
select * from t12;

在这里插入图片描述

update t12 set comment='你还好吗!';
select * from t12;

在这里插入图片描述

评论区:如果评论人修改了评论内容,那么就需要对评论表进行更新,更新表的同时评论的发布时间也会更新为修改表的时间。

5. enum 和 set

  • enum(‘选项1’, ‘选项2’, ‘选项3’ …);
  • set(‘选项1’, ‘选项2’, ‘选项3’ …);
  • 在定义 enum 字段时需要提供若干个选项的值,在设置 enum 字段值时只允许选取其中的一个值。
  • 在定义 set 字段时需要提供若干个选项的值,在设置 set 字段值时可以选取其中的一个或多个值。

调查表案例

create table votes(
    name varchar(20),
    gender enum('男', '女'),
    hobby set('敲代码', '打游戏', '游泳', '乒乓球', '羽毛球')
);
desc votes;

在这里插入图片描述

insert into votes values ('刘备', '未知', '敲代码'); # 插入失败
insert into votes values ('刘备', '男', '敲代码');   # 插入成功
insert into votes values ('刘备', '女', '敲代码');   # 插入成功
insert into votes values ('刘备', '0', '敲代码');    # 插入成功
insert into votes values ('刘备', NULL, '敲代码');   # 插入成功
insert into votes values ('刘备', '1', '敲代码');    # 插入成功
insert into votes values ('刘备', '2', '敲代码');    # 插入成功
insert into votes values ('刘备', '3', '敲代码');    # 插入失败
select * from votes;

在这里插入图片描述

  • enum 提供了若干个选项,但是只能选择一个选项,但是不能插入不存在的选项。
  • 出于效率考虑,这些值实际存储的是"数字",每个选项值依次对应如下数字:1、2、3 … 65535。当我们添加枚举值时,也可以添加对应的数字编号。
  • 插入 0 / NULL 也能成功插入且对应的是:有但是为空串 / 什么都没有。
insert into votes values ('关羽', '男', '敲代码');
insert into votes values ('关羽', '男', '打游戏');
insert into votes values ('关羽', '男', '敲代码,打游戏,游泳');
insert into votes (name) values ('张飞');
insert into votes values ('曹操', '男', 7);   
insert into votes values ('孙权', '男', 31);  
insert into votes values ('孙尚香', '女', 0);
insert into votes values ('孙策', '男', 1);
insert into votes values ('周瑜', '男', 2);
select * from votes;

在这里插入图片描述

  • set 提供了若干个选项,可以选择多个选项。
  • 而且出于效率考虑,这些值实际存储的是“数字”,且以位图的方式进行存储,每个选项值依次对应如下数字1、2、4、8、16、32 … 最多64个。当我们添加枚举值时,也可以添加对应的数字编号 (例如:7的二进制为00111,对应前三个选项。31的二进制为11111,对应所有选项)
  • 不建议在添加枚举值,集合值的时候采用数字的方式,因为不利于阅读。

查找数据:

select * from votes where gender='男';

在这里插入图片描述

# 只能找出爱好是打游戏的,但是不能找出爱好有打游戏但还有其他爱好的人
select * from votes where hobby='打游戏'; 

在这里插入图片描述

  • 集合查询使用find_ in_ set函数: find_in_set(sub, str_list)
  • 如果 sub 在 str_list 中,则返回下标,如果不在,返回0,str_list 用逗号分隔的字符串。
select * from votes where find_in_set('打游戏', hobby);

在这里插入图片描述

# 但是这样无法找出两个爱好的
select * from votes where find_in_set('打游戏,游泳', hobby); 

# 必须这样写
select * from votes where find_in_set('打游戏', hobby) and find_in_set('游泳', hobby); 

在这里插入图片描述

select * from votes where hobby=31;

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值