当前位置: 首页 > article >正文

MySQL之数据类型

目录

一 数值类型

1 int类型,以tinyint为例

范围:

越界问题:

验证:

2 bit(位)

应用:

显示问题:

3 小数

1 float[(M,D)] [unsigned]

范围:

2 decimal

精度问题

二 文本、二进制类型

1 char(L)

对一个字符的理解:

对固定长度的理解:

对于空串:

示例

 2 varchar

变长:

L:

三 时间日期

四 String

存储

示例

插入

查询

对enum:

对set查询


 

前置理解:

MySQL中有非常多的数据类型。之所以会有这么多的数据类型,是因为我们会根据实际的应用场景去选择合适的结构类型。

比如说对于性别的选择,只有男女这样的选项的话,就可以设置成bit(1)。

不同的数据类型会有不同的特性,对于空间或者效率上的利用各有特色。因此我们学习数据类型,结合实际的应用场景,选择最适合应用场景的数据类型进行数据的存储。

存储数据的时候,数据类型的精细化,可以帮助我们更合理地使用文件空间。

我们分别从整形,浮点型,文本二进制类型,时间类型,String类型进行理解。

一 数值类型

1 int类型,以tinyint为例

范围:

由于默认是有符号的,所以在没有指定无符号的情况下,范围是-128——127.

但是如果是有符号的话,默认范围就是0——255

越界问题:

(默认是有符号类型进行创建)我们先插入几条在数据范围内的数据,发现可以被成功插入;我们插入在数据范围之外的数据,发现就会告警,不允许进行插入。

 

其实这时候我们就可以发现,MySQL对于越界问题的一个处理方式是直接告警,不能进行插入。这和我们之前学习语言的时候不太相同,为什么会发生这样的情况呢?

这和数据的存储和数据库的要求有关:数据库要求数据的存储具有可信度的。而数据在底层是以二进制的方式进行存储,如果超出了对应的存储范围,仍然要进行存储的话,就会发生截断。如果截断的话,数据的可信度就不高了。因此对于越界行为的处理,MySQL是直接进行警告不允许插入的。直接就终止了对应的操作。

也就是说:在MySQL中,只有符合数据范围的数据才会进行插入,否则就不能。

其实这样设计可以倒逼程序员去遵循对应的数据的规则,谨慎选择对应的数据类型,这也是约束的一种体现。约束程序员规范存储数据。

好处:MySQL有了这样的约束之后,就保证了数据库内部存储的数据都是可以预期的。(我们可以根据数据类型推测出存储的数据的一些性质)

总而言之,除了对功能性的基本需求之外,MySQL还有对非功能性的规范。数据类型的本质就是一种约束,约束程序员去规范输入,保证数据库内部存储的数据都是可以预期的

验证:

用无符号类型的数据类型再来验证上述的结论

 我们也能得到这样的结论。

其实我们声明unsigned的时候,除了对数据范围的一个声明,也声明了语义。比如人的年龄,身高,体重等不可能是负数,就可以用unsigned来存储。

我们存储的时候,使用tinyint存储不下的数据,tinyint unsigned可能也存储不下,这时候我们优先考虑的应该是是否能正确存放数据,对非功能性的要求就没有那么严格了,可以将tinyint提升为int或者bigint。

tinyint,int,bigint等都是类似的,只不过范围不同

2 bit(位)

声明bit的时候是这样声明的:

bit[(M)]

[]标识里面的内容可以省略,如果省略的话,默认就是1.里面的M标识位数,范围是从1——64

应用:

如果非常注重空间的话,就可以使用bit来存储。比如标识男女,是否是会员……

显示问题:

我们分别设定int和bit(8)的插入同一个数据,观察相应的产生的影响:存储的时候是可以存进去的,但是取的时候不太相同

我们分别对不同的类型插入相同的数字,会发现插入的时候是没有问题的,但是筛选的时候结果却不一致?

这和bit类型的数据存储有关:

相比于int,存的时候存的是int,取得是int。因此存取数据是一样的

但是bit的话,存的时候是按二进制存的,取得时候会以二进制的代码显示(ASCII码)。又因为数据库不让我进行截断,因此导致的一个影响是bit的有一些数据不可显。

但是对于这一部分不可显的数据仍然是存储在表中的,我们也可以通过条件筛选进行筛选出来

3 小数

1 float[(M,D)] [unsigned]

M标识显示的长度,D是小数点后的位数

实际存储位数和显示位数:我们之前格式化输出的时候指定位数,就是一个指定的显示长度。但是这个数据实际上存储的位数和显示的有区别的

范围:

如果我们是 float(4,2)的话,范围是-99.99——99.99 如果是float(4,1)的话,范围是-999.9——999.9以此类推

MySQL的小数是支持无符号的,这影响了数据范围,直接将负数的一部分舍去。

 

 我们可以看到对于浮点数会进行四舍存储,也就是即使超出了最后一个精度范围的位置我们依然可以填入数据。但是最后的结果是一样的。

(虽然不是取整,但是对比零向取整的思想是差不多的)

2 decimal

decimal使用的时候和float等是差不多的,只不过精度上更精确

decimal[(m,d)] [unsigned]

m指定长度,d表示小数点的位数

精度问题

为什么存储更精确?

浮点数的存储肯定会有精度损失的问题的。整数部分的规则/2取余数,小数点部分*2取整,小数点可能无法取整完毕。

float表示的精度大约是7位,

decimal m最大是65,d最大是30.如果被省略,m默认是10,d默认是0.

如果我们期望浮点数的精度更高,推荐使用decimal

二 文本、二进制类型

1 char(L)

是一个固定长度的字符串,L表示可以存储的长度,单位是字符,最大是255

对一个字符的理解:

在MySQL中,一个字符既可以代表一个英文字母,又可以代表一个汉字(这与语言中有所区别,语言中一个汉字可能是多个区别)

对固定长度的理解:

不管有没有用到对应的长度,该定长字符串都会用长度L的字符空间来存储

对于空串:

这里我们插入的时候可能会有空串,这是在筛选的时候不显示的。但是实际上又有数据

示例

最后一行是空串

 2 varchar

varchar(L)

和char的理解差不多,不过他是一个可变长度的字符串,L标识字符长度,最大可以是65535个字节。

变长:

<=的意思。如果超过规定的范围仍然是不允许插入的。变长的话最后存储的时候会根据实际存储的数据改变长度,起到节省空间的效果(同等的,会牺牲一部分的效率)

L:

他有两部分:1——3个字节用来记录数据大小,有效字节:65532。

因为要是变长的,肯定会有对应的部分记录数据的大小,会根据有效存储的数据的长度决定使用多少个字节数保存。

除去这一部分,剩下的都是我们可以用来保存数据的空间。需要注意的是,如果我们使用utf8编码的话,对于L最大只能写21844 。(utf编码一个字符3个字节),同理对于gbk,L最大是32766

 对比char和varchar类型

定长可能会造成空间的浪费,但是效率比较高

变长节省了磁盘空间,但是相应的效率比较低

因此我们应该根据实际的需求进行选择

三 时间日期

常用的有以下三类

date 'yyyy-mm-dd' ,占用三字节

datetime 'yyyy-mm-dd HH:ii:ss' 占用8字节

timestamp:时间戳 格式和datetime完全一致,占用四字节

创建三列分别用来存储对应的类型,timestamp比较特殊,不为空并且默认值是当前的时间戳。我们利用这个类型的时候,会自动更新插入对应数据的时间。是由系统自动获取的

四 String

Stirng有enum和set两个类型,

enum:枚举,单选类型

set:集合,多选类型

存储

enum的存储:

该类型提供了若干选项的值,但是实际存储的时候只是存储了一个值,并且实际是按照数据进行存储的。对应正常的数组下标

约束性更强,只能在枚举的选项中进行选择,如果超出对应的选项就会报错。

set的话,数据存储也是在底层存储的数字。但是存储的时候,实际上是利用了位图这样的结构进行存储的(在之前的Linux选项的章节中介绍过,这里不介绍)

示例

插入

 

 0,1标识有无,具体的数据标识具体的值

查询

对enum:

既可以利用下标又可以利用对应的选项进行查找

对set查询

由于set的底层是位图,所以我们只用=查找的话,只能筛选出只有的,而非包含的。如果要筛选出包含的话,应该用对应的函数进行查找

find_in_set

mysql> select * from person where find_in_set('代码',hobby);

find_in_set的第一个参数是标识需要查找的对应的条件,第二个是在哪里查找。比如上述的语句就是在hobby里查找包含代码的数据

 


http://www.kler.cn/a/10186.html

相关文章:

  • Chromium 中sqlite数据库操作演示c++
  • 2024年11月10日系统架构设计师考试题目回顾
  • 【C/C++】CreateThread 与 _beginthreadex, 应该使用哪一个?为什么?
  • 力扣 LeetCode 977. 有序数组的平方(Day1:数组)
  • 分布式----Ceph部署
  • Linux如何将文件或目录打成rpm包?-- rpmbuild打包详解
  • 一个评测模型+10个问题,摸清盘古、通义千问、文心一言、ChatGPT的“家底”!...
  • 基于Spring Boot和Vue3打造一个属于自己的博客平台CodeInsight
  • 【AIGC】7、CLIP | OpenAI 出品使用 4 亿样本训练的图文匹配模型
  • 高可用同时数千人在线的微服务架构需要做些什么工作
  • 2023年的深度学习入门指南(3) - 动手写第一个语言模型
  • [NOIP2017 提高组] 逛公园 (题解)
  • macosBrew
  • 华纳云:php怎么判断域名跳转
  • SpringSecurity中用户表单登录验证源码分析
  • jQuery位置方法
  • 【Cesium 编程第一篇】概述、环境搭建、界面介绍
  • 总结815
  • Android Textview Button 等基础组件学习
  • Java-红黑树的实现
  • Python 小型项目大全 76~81
  • 【数据结构】二叉树的概念及结构
  • 在线文章生成器-文章生成器在线生成
  • 文件小注意
  • 摩兽Pesgo plus首发爆卖,全网关注度破亿!中国潮玩跨骑电自浪潮已至?
  • 家装产业的数字化,正在成为越来越多人的新共识