MySQL——3、数据类型

数据类型

1、数据类型分类

2、数值类型

2.1、tinyint类型

首先创建t1表,只有列属性num,类型为tinyint类型:

创建成功后我们可以通过以下三种方式查看表信息:
1、查看当前数据库存在哪些表:show tables;
2、查看表结构:desc t1;
3、查看创建表的信息:show create table t1 \G

接着我们向该表插入一些值:

由于tinyint的取值范围为-128~127,所以上面插入都是成功的。
下面试试插入范围之外的值:

在创建表的时候,指明tinyint类型,后面还可以跟上unsigned表示无符号类型。下面我们创建表t2,只有一个num列的无符号tinyint类型:

接着我们试着插入一些数据:

此时无符号的unsigned tinyint类型取值范围是0~255,我们插入范围内的值是可以插入成功的,当我们插入范围之外的值,MySQL会直接拦截我们。至于其他的类型,如small int、medium int、int、bigint可自行测试。

在C/C++中,我们赋值一个大整数给char类型的数据,一般情况下不会报错,会自动发生截断。而在MySQL中,如果我们向MySQL特定的类型插入不合法的数据,MySQL一般都是直接拦截我们,不让我们做对应的操作!反过来,如果我们已经有数据被成功插入到MySQL中了,那么插入的数据一定是合法的。
所以MySQL中,数据类型本身也是一种约束。------倒逼程序员,让程序员尽可能进行正确的插入。约束约束的是使用者。如果你不是一个很好的使用者,MySQL也能保证插入数据的合法性。
通过这种方式,就可以保证数据库中的数据是可预期的,完整的。


2.2、bit类型


使用样例:

表t3中的online用来表示用户是否在线,由于只有一个比特位,所以只能表示0/1,其中0表示不在线,1表示在线。我们插入数据,发现只能online这一列的时候,只能插入0/1,超出的数值是无法插入的。

另外我们查看一下插入的数据:

我们发现online这一列默认显示的是十六进制数,如果我们要转换成十六进制可以这样:

下面我们修改online这一列的属性,插入一些更大的数值看看:

另外,bit类型的位数是1~64,如果超出64位创建表的时候就会失败,如果不写位数默认就是1位。如下图:


2.3、小数类型

2.3.1、float


使用样例:


salary的取值范围在-99.99~99.99,所以其他数值是无法插入的。


插入的数据如果有多个小数,会进行四舍五入。当时需要注意四舍五入后也需要在取值范围内,假设插入数据为99.995,四舍五入后就是100.00,这样也是无法插入的。

下面我们再看看使用无符号float类型的样例:

float这里无符号类型很简单粗暴,直接将负数部分砍掉。

下面修改salary属性,改为默认的float类型,然后插入数据:


我们不指定位数和精度,默认也是只保留两位小数的,但是我们可以看到插入数据的时候,连整数精度都会丢失。


2.3.2、decimal

首先来对比float和decimal的精度:

我们发现float是有精度丢失的,而decimal精度更高


3、字符串类型

3.1、char


使用样例:

如图,大于两个字符就无法插入了。接着我们再验证一下汉字:

对于中文汉字也是如此。这里字符串char类型是以字符为单位的,不管是数字、字母、汉字,一个都算一个字符。另外,utf8mb3编码中,一个中文汉字一般是占3个字节,两个字符中文汉字那就是6个字节,而在gbk编码中,一个中文汉字则占2字节。


3.2、varchar


使用样例:

由于我们设定的长度为6,所以超过6个字符就无法插入了。另外,我们注意到上面最大长度为65535个字节,那么在utf8mb3编码下,我们需要让65535/3=21845个字符。


实际上,varchar还需要1~3个字节来记录数据的长度,假设长度拉满,那么实际上存储的字节数就是65532。如果是在utf8mb3中,就需要/3。如果是在gbk中,就需要/2。


在上图中,我们修改了字符长度为21845,由于还需要保存数据长度,所以肯定不行。但是为什么修改长度为21844也不行呢?这是因为MySQL中一行最大长度为65535个字节,我们前面还有一个int类型的数据,所以实际上最大也只能是21842个字符。

如果我们另外创建一个表,单独存放一个变长字符串,那么就可以达到21844个字符,这时候没有其他属性影响,那么该属性可以独占一行最大长度65535个字节。


3.3、char和varchar比较


3.4、日期和时间类型


使用样例:

timestamp在MySQL比较老的版本中,当我们进行插入或者修改的时候是会自动进行更新的。但是这里我使用的MySQL8.0,所以不会自动更新了,需要我们再创建表的时候设置,如下:


MySQL较新的版本需要我们手动显示定义。现在当我们插入一行或者修改属性的时候,第三个字段timestamp就会自动更新:

timestamp可以应用在用户发表评论的时候,当用户发表了,插入评论信息到数据库中,自动设置时间戳。当用户修改评论的时候,对应数据库的时间戳也会自动修改。datetime就是用来存储固定的时间的。


3.5、enum和set

使用样例:



gender性别不能插入除男和女以外的值,当然也可以采用常量的下标1/2,从下标1开始,下标也不能超出范围。


插入集合的时候,也是不能出现除集合意外的值。可以插入多个选项,中间用逗号分隔开。


另外,我们发现enum和set默认是可以为空的,所以在插入表t13的时候,我们可以只插入username,剩下的gender和hobby默认为空。


接着我们给hobby插入了一个0和一个1,我们发现插入0的这一行hobby为空。这就需要对比NULL和''了,NULL表示为空,而这里则表示空串。空串和NULL是不一样的。插入1则表示的是代码。
下面我们插入2,那么对应的应该就是羽毛球了:

那如果我插入3呢?是乒乓球吗?

并不是,这里是代码和羽毛球。因为代码是用第一个比特位来表示的,羽毛球是用第二个比特位来表示的。插入3,3的二进制表示为11,所以插入了代码和羽毛球。所以乒乓球应该是第三个比特位来表示的,如果我们想单独插入一个乒乓球用数字的方式,那么就应该插入4。

hobby总共有五个选项,每个选项对应第一个比特位到第五个比特位,如果我想插入所有的选项呢?那就是2^5-1=31。下面我们插入31看看:


enum和set的查询:

enum查询我们可以使用枚举常量,也可以使用下标来查询。


我们在查询set的时候,这里的查询条件是严格匹配的,显示的是只有爱好为羽毛球/代码+羽毛球的人员信息。但是我们还期望的是筛选出爱好包含羽毛球的所有人员信息,就需要使用find_in_set函数。



那如果我们要找爱好中包含羽毛球和代码的呢?我们上面测试在abc中查找ab返回是0。
实际上我们where子句可以跟and,把多种结果级联起来。关于where子句我们后面会做介绍。

相关推荐
Amctwd15 分钟前
【SQL】如何在 SQL 中统计结构化字符串的特征频率
数据库·sql
betazhou1 小时前
基于Linux环境实现Oracle goldengate远程抽取MySQL同步数据到MySQL
linux·数据库·mysql·oracle·ogg
lyrhhhhhhhh1 小时前
Spring 框架 JDBC 模板技术详解
java·数据库·spring
喝醉的小喵2 小时前
【mysql】并发 Insert 的死锁问题 第二弹
数据库·后端·mysql·死锁
付出不多3 小时前
Linux——mysql主从复制与读写分离
数据库·mysql
初次见面我叫泰隆3 小时前
MySQL——1、数据库基础
数据库·adb
Chasing__Dreams3 小时前
Redis--基础知识点--26--过期删除策略 与 淘汰策略
数据库·redis·缓存
源码云商3 小时前
【带文档】网上点餐系统 springboot + vue 全栈项目实战(源码+数据库+万字说明文档)
数据库·vue.js·spring boot
源远流长jerry4 小时前
MySQL的缓存策略
数据库·mysql·缓存
纯纯沙口4 小时前
Qt—用SQLite实现简单的注册登录界面
数据库·sqlite