数据库数据类型,数据值类型,字符串类型,日期类型详解

前言❤️❤️

hello hello💕,这里是洋不写bug~😄,欢迎大家点赞👍👍,关注😍😍,收藏🌹🌹

在定义数据表时需要指定各个列的数据类型,数据库中的数据类型跟Java中的区别还是比较大的,有很多新的概念,这篇文章就从示例和定义对数据类型进行解析

🎇个人主页:洋不写bug的博客
🎇所属专栏:数据库
🎇mysql8.0和navicate的安装:mysql安装教程
🎇铁汁们对于MySQL数据库的各种常用核心语法,都可以在上面的数据库专栏学习,专栏正在持续更新中🐵🐵,有问题可以写在评论区或者私信我哦~

1,数据库跟Java的对应

下面这样一段Java代码,就是在Student类中定义了一些属性,然后创建对象

java 复制代码
public class Student {
    private String name;
    private int age;
    private char gender;
    private int class_id;

    public Student(String name, int age, char gender, int class_id) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.class_id = class_id;
    }
}
java 复制代码
public class Test {
    public static void main(String[] args) {
        Student student = new Student("张三",18,'男',1);
    }
}

再看下数据库中存的这样一个学生表,是不是跟这段Java程序有点联系

看这整个表,包含各种属性,与Java中的类有着密切的对应关系
这个表在数据库设计时就称它为实体
而数据行,就相当于Java程序中的对象

它们之间的关系表示如下图,

2,数据值类型数据

数据库中的数据类型分为两大类:数据值类型数据和字符串类型数据

数据值类型数据表如下:
注:表中的大小这列byte代表字节,类型这列中的[ ]代表可以写,不写有默认值,也不会报错。

接下来是常用数据值类型数据的解析:
BIT[(M)] : 大小只写了一个bit
这个BIT表示大小是动态的,这是在数据库中一个全新的概念,我们在括号里M的位置填数字,就代表其有几个比特位

例如,填BIT(3),就是有三个比特位,就可以存储0---7的整数

填BIT(8),这个数据就是有三个比特位,可以存储0---255的整数

这里M的值最大就是64 ,就是这个数据最多可以占64个比特位
如果省略M的话,就是默认只有一个比特位,那就只能表示0和1

TINYINT[(M)]: 这个数据的大小就是固定的,为1byte(字节),表示的数据范围也是固定的

那既然大小是固定的,那这个括号里的M是干什么的呢?
其实这个M跟BIT中的M表达的意思是不一样的,这里的M的意思就是显示宽度

比如这个数据的值16,显示宽度应该是两个

在括号里填上4的话,这时候显示16时就会在16的前面补上两个空格;

在括号里填上1的话,显示宽度比16小,那就是还按正常显示
总结一下,就是当M的值比数据的宽度大时,显示时就在数据前面补空格,当M的值比数据的宽度小时,这时候就忽略M,还按正常显示

BOOL: 这个其实就是TINYINT(1)的同义词,是0或者非0,0的话就代表是假的,非零(1---9就代表为真)

SMALLINT[(M)]: 其实就是相当于Java里面的short,大小为2个字节,M同样是显示宽度的意思。

MEDIUMINT[(M)]: 大小为3个字节,M表示显示宽度。

INT[(M)]: 大小为4个字节,相当于Java中的int,M表示显示宽度。

BIGINT[(M)]: 大小为8个字节,相当于Java中的long,M表示显示宽度。

FLOAT[(M,D)]: 大小为4个字节,相当于Java中的Float
M表示数据总位数,D表示小数点后的数据位数

例如1234.5,那么总位数就是5,小数点后的位数就是1,FLOAT 大约可以精确到小数点后七位。
FLOAT[(M,D)]中的M和D的概念又跟前面不同,既不是控制比特位数,也不是控制显示长度,而是控制小数数值位的分配,M和D怎么填,会直接影响小数的显示精度。

DOUBLE[(M,D)]: 这个相当于Java中的Double,大小为8个字节,M和D跟FLOAT的概念是一样的,大概可以精确到小数点后的十五位。

  • 注:在实际开发中,我们一般是不用FLOAT和DOUBLE的,因为精度可能会损失,那么还有一个更牛的数据类型,使用它是不会造成精度损失的,他就是DECIMAL

DECIAMAL[M(,D)]: 这个就相当于Java上的BigDecimal,在Java中很多问题使用double都可以解决,因此BigDecimal铁汁们在Java中可能使用的不多
这里M表示的是小数总的位数,D表示的是小数点后的位数
M的最大值就是65,D的最大值是30,省略M,就默认M是10,省略N,就默认N是零

DECIMAL的大小是动态的,之前有种说法就是其占8个字节,这种说法是不正确的
DECIAML存储时是把长数据拆分为一个个int来存储的:

一个int的最大存储时 21亿左右,那就是21 0000 0000,就是10位

但并不是所有10位数都可以表示,所有的9位数(或以下)还是都可以表示的,9 9999 9999及以下都可以表示
123456789987654321.123456789987654321

上面这个小数,就是小数后18位,小数前18位,一共36位

如果用int去表示,那就刚好要拆成4份,需要个4个int,也就是16个字节
因此,DECIAML的大小是不确定的,会随着长度的改变而改变。
123456789 987654321.123456789 987654321 123

像上面这个小数是39位,用4个int表示还多出来3位,
多出的这三位并不是用int去表示,为了避免存储的浪费,还有一个机制,剩下的这三位就用SMALLINT(最大能表示65536,最多能存储4位)来存储
在实际开发中,在描述金额的数据类型时,一般会有下面这两种方法:

1,就是直接使用Decimal,不丢失精度(但是这样就比较麻烦 ,Decimal类型的数据不能使用"+"或者"-"符号来进行运算,要使用add方法之类的)。

2,那还有一种方法就是,我们把金额单位换成更小的单位,比如把金额换成比厘还小的单位,用int型去记录

3,字符串类型数据

下面是字符串数据类型的表

1,基础解析

CHAR[(M)]: 这里的M表示的是字符串的固定长度 ,M的最大值是255,也就是CHAR最多能存255个字符

如果字符串长度只是4,定义M值为6,那么还是占用六个字符的存储空间,在这个字符右侧补空格(前面的TINYINT[(M)]是在左边补空格,这个是在右侧补空格)

如果定义M值为4,但是存入字符串的长度为6,那数据库就会报错
CHAR适用于存一些长度固定的数据,比如身份证号,银行卡号之类的

VARCHAR(M): M表示的就是最大可以存储的字符个数,这个就适用于那些长度不固定的数据
如果数据没有达到这么多位,并不会补空格和消耗消耗存储空间,因此VARCHAR是我们最常用的字符串类型

比如说存储"abc"这个字符串,但是M定义为10,那其实还是按占用三个字节的存储空间来存的
VARCHAR中字符串长度(在CHAR中是确定的,字符串的长度包括填充的空格数)是不确定的
因此在存储空间中还要分出字节来记录长度,长度不超过 255 时,用 1 个字节记录长度;超过 255 时,用 2 个字节记录长度
这里的M最大是65535,也就是最多能占65535个字节

如果使用ascii编码,一个字符占用一个字节(可以在命令行工具中查询,如下图 ),是可以表示65535个字符的

但是现在大多采用的utf8mb4编码,一个字符占用4个字节,这65535个字节还要拿出来两个来记录字符串长度

(65535 - 2) / 4 = 16383 ,也就是在 utf8mb4 字符集下,VARCHAR 类型最多能表示 16383 个字符

TINTEXT: 里面也是存字符,属于小文本,最多能存储255个字节,适用于存储比较简短的东西。

TEXT[(M)]: 这里的M是显示宽度的意思,不重要,基本上不用去看

TEXT存储的长度就增加了

可能这里有的铁汁就会说,那TEXT不就跟VARCHAR几乎没什么区别嘛?

其实是有区别的,在采用utf8mb4编码时,最多能在VARCHAR中存储16383 个字符 ,如果存多了,数据库就会报错

但是在TEXT中,如果存多了,就会往上升级,生成中文本类型,大文本类型,大文本类型最大存储空间为4GB!

MEDIUMTEXT: 中文本类型,最大长度为16MB(2 ^ 24 - 1)个字节

BIGTEXT: 大文本类型,最大存储空间为4GB(2 ^ 32 - 1)个字节。

BINARY: 存储二进制字节,这里的M表示二进制字节的长度,这里与CHAR比较类似,但是只是多出来的空间不会被空格填充,会闲置下来。

那什么是二进制字节,什么是字符串呢?

创建一个excel表,用记事本来打开,就会发现里面是一堆乱码,这里就是用二进制存储的(示例如下:)


像下面这种,创建一个文本文档,写上一句话,这我们能看懂,就是用CHAR和TEXT这类来存储的。

那么后面的这些存二进制的数据类型,就不再细说了,对照着表大概了解下就行了
现在MySQL中已经不存这些数据了,有更好的方式去保存二进制数据

那么最后一个部分就是ENUM和SET:

ENUM就是枚举,这是JavaSE中的内容,后续会在JavaSE最后的一篇博客更新,大家可以关注下。

SET就是一个集合,里面保存许多元素,比如保存新能源汽车:问界M7,小米yu7,理想L9...

这些东西也不怎么在数据库中使用这些了,只是了解一下就可以了

现在一般只是让数据库中存储一些关系型数据
前面的那些二进制,可以去存到一个更大的文件服务器中,只在数据库中存储云服务器的链接即可;
我们举个例子:

这样的一张图片,如果在数据库中存储它的二进制数据,那么会存很多内容,但是如果我们存这张图片的链接,那么在数据库中占用的空间就很少了

下面就是存储链接,很短:

https://i-blog.csdnimg.cn/direct/27d40320c8f54580b285be2c48a0dc53.png
至于ENUM和SET,直接在程序中就判断好,用INT类型或者VARCHAR类型存储下来即可,也没有必要把这些搞到数据库中去。

2,CHAR和VARCHAR的使用

看下这段代码,这里创建一个CHAR字符串(c),一个VARCHAR字符串(v),两个字符串都插入'ab '(两个空格)之后
再查询,发现CHAR字符串后面的两个空格没有了
这就是CHAR字符串的查询删除末尾空格机制

前面说了,CHAR字符串如果长度没有M,就自动往后加空格
因此CHAR就设置了这样一个机制,查询时删除字符串后的所有空格

CHAR和VARCHAR的使用场景如下:

  • 如果数据确定长度都一样,就使用定长 CHAR 类型,比如:身份证,md5,学号,邮编
  • 如果数据长度有变化,就使用变长 VARCHAR,比如:名字,地址,但要规划好长度,保证最长的字符串能存的进去
  • 定长 CHAR 类型比较浪费磁盘空间,但是效率高。
  • 变长 VARCHAR 类型比较节省磁盘空间,但是效率低。
  • 定长 CHAR 类型会直接开辟好对应的存储空间。
  • 变长 VARCHAR 类型在不超过定义长度范围的情况下用多少开辟多少存储空间。

4,日期类型

下面是日期类型的表格:

TIMESTAMP: 这个是很早的用来表示时间的数据类型,那时候内存比较金贵,因此数据只有四个字节,而且这个数据类型到2038年就失效了,会溢出,也就是十几年之后的事情,因此,这个数据现在已经完全不再使用了。

DATATIME: 括号里的fsp表示的就是秒数保留几位小数,大小为8个字节,这个在现在使用非常的多。

DATA: 只显示日期,不显示是几时几分,大小为3个字节。也是经常使用。

TIME: 表示具体的时分秒,不显示几月几号,大小为3个字节。

YEAR: 显示4位格式的年份,大小为1个字节。
我们可以在命令行控制台中试一下查看日期:

结语💕💕

这些数据类型虽然很多很复杂,但是实际上在创建表的时候使用的也就那几个,比如varchar,bigint,smallint这些,这些概念不需要完全记住,一些后面要用到再去查询也可以
以上就是今天的所有内容啦~完结撒花~🥳🎉🎉

相关推荐
Paraverse_徐志斌3 小时前
RAG架构(检索增强生成)与向量数据库
数据库·ai·llm·embedding·milvus·rag
NineData5 小时前
NineData将亮相第27届GOPS全球运维大会,并带来技术演讲
运维·数据库·ninedata·智能·ai agent·数据管理工具·gops全球运维大会
Java水解5 小时前
MySQL 中 ROW_NUMBER() 函数详解
后端·mysql
不良人天码星5 小时前
谈谈redis的持久化
数据库·redis·缓存
qq_479875436 小时前
TimerFd & Epoll
java·服务器·数据库
绵绵细雨中的乡音6 小时前
MySQL 数据库核心操作全解析:从创建到备份与连接管理
数据库·oracle
wayuncn7 小时前
哈尔滨电商企业服务器托管方案
运维·服务器·数据库
重整旗鼓~8 小时前
27.Redisson基本使用和可重入性
数据库·redis·缓存
瑶总迷弟8 小时前
使用 Docker 和 docker-compose 快速部署 openGauss
linux·数据库·云原生·eureka