MySQL——数据类型(一)

目录

一、前言

二、数值类型

[2.1 tinyint [unsigned]](#2.1 tinyint [unsigned])

[2.1.1 插入合法数据](#2.1.1 插入合法数据)

[2.1.2 插入边界数据](#2.1.2 插入边界数据)

[2.1.3 插入不合法数据](#2.1.3 插入不合法数据)

[2.1.4 结论](#2.1.4 结论)

[2.2 bit [n]](#2.2 bit [n])

[2.3 float [(m, d)] [unsigned]](#2.3 float [(m, d)] [unsigned])

[2.3.1 float 特性](#2.3.1 float 特性)

[2.3.2 插入整数部分大于 m-d 的数字](#2.3.2 插入整数部分大于 m-d 的数字)

[2.3.3 插入小数部分大于 d 的数字](#2.3.3 插入小数部分大于 d 的数字)

[2.3.4 插入一个五入后整数部分会多余 m-d 的数字](#2.3.4 插入一个五入后整数部分会多余 m-d 的数字)

[2.3.5 float 范围总结](#2.3.5 float 范围总结)

[2.4 decimal [(m, d)] [unsigned]](#2.4 decimal [(m, d)] [unsigned])

三、字符串类型

[3.1 char(L)](#3.1 char(L))

[3.2 varchar(L)](#3.2 varchar(L))

[3.3 char 与 varchar](#3.3 char 与 varchar)


思维导体可参考链接:

数据类型.xmind · 夜夜亮晶晶/MySQL - Gitee.comhttps://gitee.com/bright-and-sparkling-at-night/mysql/blob/1c557ac01b63e74f67821505e30c6a8e5b5cf095/2024-9/%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.xmind

一、前言

数据类型分类:

在上表中,标红的是接下来会讲到的知识, 使用[ ]的是可选项,使用( )的是必选项。

二、数值类型

2.1 tinyint [unsigned]

tinyint 是占用空间比较小的数值类型,用来存储范围内的整型,

取值范围:有符号:[-128, 127] 无符号:[0, 255]

从它的存储范围不难看出, tinyint 在内部占用的是 8bit 也就是 1Byte ,

下面来看以下当输入合法和不合法时, MySQL 会做出什么响应:

这里首先要创建表,我们分别创建了一个有符号和一个无符号的 tinyint 类型:

cpp 复制代码
mysql> create table test1(
    -> class tinyint,
    -> age tinyint unsigned);
Query OK, 0 rows affected (0.05 sec)

其次来看看三种插入情况:

2.1.1 插入合法数据

cpp 复制代码
mysql> insert test1(class, age) values(27, 18);
Query OK, 1 row affected (0.03 sec)

2.1.2 插入边界数据

cpp 复制代码
mysql> insert test1(class, age) values(-128, 255);
Query OK, 1 row affected (0.01 sec)

2.1.3 插入不合法数据

对于有符号数(-∞, -128)∪(128, +∞) 对于无符号数(-∞, 0)∪(255, +∞) MySQL会直接报错,不允许插入:

cpp 复制代码
​​​​​​​mysql> insert test1(class, age) values(-129, -1); 
ERROR 1264 (22003): Out of range value for column 'class' at row 1

这里就可以得到结论:

2.1.4 结论

如果超过存储范围,MySQL会直接拦截用户操作确保数据的合法性。这保证了MySQL存储数据的绝对安全,同时倒逼程序员存储合法的数据。

2.2 bit [n]

bit 默认为 1bit ,可以使用 bit[n] ,指定 bit 的位数,最多为 64bit。

下面一起来验证一下,首先还是创建一个表:

cpp 复制代码
mysql> create table test2(
    -> haha bit);
Query OK, 0 rows affected (0.03 sec)

现在来插入数据,先插入 0 和 1 ,发现都可以插入成功。当插入 2 时,MySQL会直接报错:

cpp 复制代码
mysql> insert test2 values(0); 
Query OK, 1 row affected (0.00 sec) 

mysql> insert test2 values(1); 
Query OK, 1 row affected (0.01 sec) 

mysql> insert test2 values(2); 
ERROR 1406 (22001): Data too long for column 'haha' at row 1

2.3 float [(m, d)] [unsigned]

m:显示总位数(整数部分+小数部分) d:指定小数位数

可以看到 m 和 d 也是使用 [] 的,所以如果不指定精度,MySQL会使用默认的精度,可以自己在自己的 MySQL 上插入数据进行验证。

此外, float 的无符号类型并不会像 tinyint 一样,将返回扩大到非负的2倍(127->255),而是直接采用截断,只可以使用有符号类型的非负数部分,例如 [-99.99, 99.99] 的无符号范围是 [0, 99.99] 。

2.3.1 float 特性

下面列出我个人总结的关于 float 存储的两个特性:

特性1:存储的整数部分位数为 m - d ,如果位数多余该范围则MySQL会报错

特性2:存储的小数部分如果多余 d,则 MySQL会四舍五入,但五入后也要满足特性1

然后我们使用 MySQL 来验证:

首先建一个表,列属性设置为 float(4, 2):

cpp 复制代码
mysql> create table test3(grades float(4, 2));
Query OK, 0 rows affected, 1 warning (0.05 sec)

2.3.2 插入整数部分大于 m-d 的数字

例如插入 101 :

cpp 复制代码
mysql> insert test3 values(101);
ERROR 1264 (22003): Out of range value for column 'grades' at row 1

可以看到 MySQL 直接报错,不允许插入

2.3.3 插入小数部分大于 d 的数字

例如插入 6.12222 和 71.8888:

可以看到前一个数字被四舍至6.12,后一个数字被五入到71.89了!

2.3.4 插入一个五入后整数部分会多余 m-d 的数字

例如插入 99.996,该数字会被五入到100.00,整数部分已经大于 m-d:

cpp 复制代码
mysql> insert test3 values(99.996);
ERROR 1264 (22003): Out of range value for column 'grades' at row 1

可以看到也是不允许插入的!

2.3.5 float 范围总结

综上所述,其实 float 的存储范围也很简单, 正负 (m-d)个9 . (d个9)

2.4 decimal [(m, d)] [unsigned]

decimal 也是浮点数,但是它和 float 相比,精度更高,存储数据更加准确,下面来验证一下:

创建表:

cpp 复制代码
mysql> create table test4(
    -> ff float(10, 5),
    -> dd decimal(10, 5));
Query OK, 0 rows affected, 1 warning (0.04 sec)

插入相同数据:

cpp 复制代码
mysql> insert test4 values(12345.123456789, 12345.123456789);
Query OK, 1 row affected, 1 warning (0.01 sec)

查看表中数据:

可以看到, float 与 decimal 虽然使用相同精度,插入相同数据,但是最后存储的结果却不一样,decimal 仍可以进行正常的四舍五入,但是 float 的数据已经发生了一些变化。

三、文本类型

3.1 char(L)

char(L):固定长度字符串,L是可以存储的长度,单位为字符,最大长度值可以为255 在 utf8 中,一个字符为 3Byte。

3.2 varchar(L)

varchar(L):可变长度字符串,可变长度字符串,L表示字符长度,最大长度值可以为21845,即 65535 Byte

3.3 char 与 varchar

关于 char 与 varchar 的用法与区别,这里一起来展开:

从上图代码可以看出来,我们都为 char 和 varchar 设置了 L = 3 ,而它们也确实可以正常插入不大于 3 个字符的数据,那么这里 char 与 varchar 有什么区别吗?

其实 char 与 varchar 的区别就类似于 vector 中的 resize() 与 reserve():

char 是预先开辟空间,无论你插入了几个字符,占用的内存都是一样的

varchar 是用多少给多少,只要不多余 L 个字符都可以,占用的内存随数据变化而变化

相关推荐
weisian15121 分钟前
Redis篇--常见问题篇6--缓存一致性1(Mysql和Redis缓存一致,更新数据库删除缓存策略)
数据库·redis·缓存
MrJson-架构师1 小时前
4.银河麒麟V10(ARM) 离线安装 MySQL
arm开发·mysql
中草药z1 小时前
【Spring】深入解析 Spring 原理:Bean 的多方面剖析(源码阅读)
java·数据库·spring boot·spring·bean·源码阅读
地球资源数据云1 小时前
全国30米分辨率逐年植被覆盖度(FVC)数据集
大数据·运维·服务器·数据库·均值算法
Ahern_2 小时前
Oracle 普通表至分区表的分区交换
大数据·数据库·sql·oracle
夜半被帅醒2 小时前
MySQL 数据库优化详解【Java数据库调优】
java·数据库·mysql
不爱学习的啊Biao2 小时前
【13】MySQL如何选择合适的索引?
android·数据库·mysql
破 风3 小时前
SpringBoot 集成 MongoDB
数据库·mongodb
Rverdoser3 小时前
MySQL-MVCC(多版本并发控制)
数据库·mysql
醒了就刷牙3 小时前
黑马Java面试教程_P9_MySQL
java·mysql·面试