MySQL——数据类型

一、常见的数据类型及分类

其中上述的数值类型包含了整形和浮点型,文本、二进制类型主要是字符串类型。

  • 整数类型(Integer Types)
  1. TINYINT:范围为-128到127或0到255(无符号),用于存储较小的整数值,如存储性别或状态信息。
  2. SMALLINT:范围为-32768到32767或0到65535(无符号),用于存储较小的整数值,如存储年龄或计数值。
  3. MEDIUMINT:范围为-8388608到8388607或0到16777215(无符号),适用于中等大小的整数数值存储。
  4. INT:范围为-2147483648到2147483647或0到4294967295(无符号),适用于一般整数值存储。
  5. BIGINT:用于存储大整数值,如存储ID或计数值。
  • 浮点数类型(Floating-Point Types)
  1. FLOAT:用于存储单精度浮点数,约占用4个字节的空间。
  2. DOUBLE:用于存储双精度浮点数,约占用8个字节的空间。
  3. DECIMAL:用于精确的十进制数值存储,适用于货币或其他需要精确计算的场景。
  • 日期与时间类型(Date and Time Types)
  1. DATE:用于存储日期,格式为'YYYY-MM-DD',如'2000-01-01'。
  2. TIME:用于存储时间,格式为'HH:MM:SS',如'18:30:00'。
  3. DATETIME:用于存储日期和时间,格式为'YYYY-MM-DDHH:MM:SS',如'2000-01-0118:30:00'。
  • 字符串类型(String Types)
  1. CHAR:用于存储固定长度的字符串,如CHAR(10)可以存储长度为10的字符串。
  2. VARCHAR:用于存储可变长度的字符串,如VARCHAR(255)可以存储长度为最大255的字符串。
  3. TEXT:用于存储较长的文本数据,例如文章内容或备注信息。
  • 枚举和集合类型
  1. 枚举(ENUM)类型:枚举类型允许你从一组预定义的选项中选择一个单独的值。在创建表结构时,你可以指定枚举类型的字段允许的值列表。
  2. 集合(SET)类型:集合类型允许你从一组预定义的选项中选择多个值,这些值之间用逗号分隔。与枚举类型不同,集合类型允许选择多个选项,而不仅限于一项。
  • 其他类型
  1. BOOLEAN:在MySQL中没有专门的BOLLEAN类型,通常使用TINTINT(1)来表示bool值,0表示false,1表示true。

二、数值类型

2.1 整型

整型包括以下几种:

它们最根本的区别就是所占用的空间大小不同,也因此导致了能够存储的数据范围不同。

2.1.1 tinyint

先来测试一下tinyint的取值范围。

我们尝试插入一些数据。

在插入合法的范围内是能够正常进行插入的,但是一旦超过tinyint的取值范围,就会不让插入了,而且当插入的数据不是整型时,也是不让插入。

在C/C++中,int tmp = 'a'最多会发出提醒,并不会报错,本质上发生了隐式类型转换。char a = 200也不会报错,会发生截断。即使你存储的数据超出了指定类型的取值范围,也并不会报错,而是发出警告并且存储溢出后进行调整的值。

在数据库中并不想C/C++那样,而是有着严格的要求。**mysql的数据类型中,符合条件才会让你操作,不符合条件直接不让操作。**在mysql的数据类型中,除了能够满足各种应用场景,还有一个特别重要的用途:数据类型本质就是一种约束!约束就是强制必须按照规则去做,约束的就是使用者,倒逼使用者,必须遵守规则!

我们再来简单测试一下无符号的tinyint。

我们尝试向tmp1列中插入一些数据,如下图:

我们在查看表t1的数据时,发现有NULL。那么NULL和空字符串' '是一样的吗?答案是不一样的。NULL和空字符串' '代表这不同的含义:

  1. NULL:在数据库中表示缺少值或未知值。当一个字段的值未知或者不适用时,可以使用NULL来表示。NULL不等于任何其他值,包括空字符串。
  2. 空字符串' ':表示一个空的字符串值。当一个字段需要有值,但是没有具体数值或字符时,可以使用空字符串来表示。空字符串是一个有效的值。

在mysql中,字符串可用单引号' '来引用,也可以使用双引号" "来引用。一般情况下在mysql中都是用单引号' '的。

2.1.2 bit

bit类型也是一种数据类型。bit类型是用于存储二进制数字的数据类型。它可以用来表示位值为0或1的数值,比如开关状态、标志位等。

如上图,我们创建了一个t2表。其中包含了列a,数据类型为int;列b,数据类型为bit(10)。括号内的10的意思就是我们指定有几个比特位。那么b的大小是10个比特位。我们再来测试一下,如下图:

确实能欧插入成功。10个bit能够存储的数据范围是0~1023。确实正如上图所示。我们再来查看一下表中的数据。如下图:

怎么表中存储的并不是我们所插入的数据呢?存储是按照我们所插入的数据进行存储的,但是bit类型在显示时,是按照ASCII码对应的值进行显示的。具体如下图:

需要注意的是,虽然bit类型可以用于存储任意大小的二进制数,但是在实际应用中,bit通常只是用于存储较小的数值。这是因为bit类型的空间效率相对较低,对于较大的数值,使用其他数据类型可能会更加合适。

2.2 浮点型

2.2.1 float

float用于存储近似值的浮点数,它表示单精度浮点数。由于浮点数是以二进制形式表示的,可能存在精度丢失的情况。下面我们通过具体实例来理解用法。

上图中我们创建了一个名字为t3的表。其中包含了一个字段a,其类型为float(4,2)。**float的语法格式为float(M,D),其中M表示总位数,D表示小数点后的位数。例如,float(4,2)表示总共4位,其中2位为小数位。**下面我们插入一些数据来看一下,如下图:

那如果是插入长度大于4的数据呢?我们再来看下图:

正如上图所示,当小数位数大于两位时,会进行四舍五入。四舍五入就会产生进位,但必须保证进位后的小数也能够满足两位,也就是整数部分不得超过两位。这里可以看到float(4,2)的取值范围是-99.994 ~ 99.994。

下面再来看一下无符号的float,如下图:

插入数据:

但是负数就不能再进行插入了,如下图:

其实在这里就可以发现,float(M,D)中的M和D限制了我们的数据范围,其次就是有符号和无符号的区别。float可以表示最大值为3.402823e+38的正或负实数,所占用的字节为4字节。

在MySQL中,如果不指定float类型的总位数和小数点后的位数,默认情况下float类型的总位数是其最大取值范围。

这里可以看到,float一旦数据较大,就会有精度损失。一般情况下提供6位精度。

这意味着float类型可以存储大约6位有效数字的数据,但实际精度可能受到存储数据时的舍入误差的影响。

2.2.2 decimal

decimal用于精确存储数字,它表示定点数,能够保证精度不会丢失。

decimal的语法格式为DECIMAL(M,D),其中M表示总位数,D表示小数点后的位数,例如,DECIMAL(10,2)表示总共10位,其中2位为小数位。

这里可以看到,decimal类型精度并没有丢失。decimal与float都是用来存储浮点数的,用法也是相同的,不同的是,decimal类型存储的数字是精确的,不会丢失精度。decimal占用的空间为8字节。

三、字符串类型

3.1 char

char类型在mysql中是一个经常使用的类型。

这里定义了一个名字为str的字段,其属性为char(5),也就是最多可存储5个字符。插入数据来看一下:

这里可以看到,一旦插入的字符长度超过5,就不会让你插入了。**【注意】在mysql中,char(5)中的5指的是5个字符,并不是5个字节。**所以在这里最多也可以插入5个汉字。

在不同编码中,一个字符所占的字节个数是不同的。比如utf8中一个字符占3个字节,而gbk中一个字符占2个字节。char(5)就是指能够最多插入5个字符。这样用户在使用时就不用关心字节数的问题了。

char也是有字符长度上限的,char的字符长度上限是255

3.2 varchar

varchar也是用来存储字符的数据类型。使用方法和char相同。

那么 varchar 和 char 有什么区别呢就char(10) 和 varchar(10) 来说明,无论char中实际存储的字符串长度是多少,char始终占用10个字符长度的存储空间 。但是varchar是一种可变长度的字符类型,意味着它只占用实际存储数据所需的存储空间。我们在varchar中只存储5个字符的话,那么varchar只占用5个字符长度的空间。

关于varchar(len),len到底是多大,这个len值,和表的编码密切相关:

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

3.3 char和varchar的比较

  • CHAR数据类型:
  1. CHAR是一种固定长度的字符类型,意味着它始终占用固定数量的存储空间。
  2. 当定义一个CHAR列时,您需要指定该列的固定长度。例如,CHAR(10)表示该列将始终存储10个字符。
  3. 无论实际存储的字符串长度是多少,CHAR始终占用指定长度的存储空间。
  4. CHAR适合存储长度固定的字符串,例如邮政编码或固定长度的标识符。
  • VARCHAR数据类型:
  1. VARCHAR是一种可变长度的字符类型,意味着它只占用实际存储数据所需的存储空间。
  2. 当定义一个VARCHAR列时,您需要指定该列可存储的最大长度。例如,VARCHAR(100)表示该列可以存储最多100个字符,但实际存储的字符串长度可以少于100个字符。
  3. VARCHAR适合存储长度可变的字符串,例如用户输入的文本或变长的描述信息。

【主要区别】

  1. 存储方式:CHAR是固定长度的,而VARCHAR是可变长度的。这意味着在使用CHAR时,数据将按固定长度存储;而使用VARCHAR时,额外的空间将被用来存储数据长度信息。
  2. 性能:CHAR由于固定长度和提前分配的空间,其性能通常比VARCHAR要快。特别是当已知要存储的字符串长度时。而VARCHAR因为其灵活性(读取时需要先读取存储字符串的长度,再访问指定长度的空间),可能稍慢一些。
  3. 空间使用:CHAR使用固定的空间来存储数据,因此可能会因为并没有使用全部空间而造成空间的浪费。但VARCHAR使用额外空间来存储数据长度信息,相对来说空间利用率较高。
  4. 可变字段:如果一个字段的数据长度可能会有所不同,使用VARCHAR可能会更好,因为它允许更大的数据长度。

选择使用哪种类型取决于具体需求。如果知道要存储的字符串的长度,并且长度是固定的,CHAR可能是一个好选择。然而,如果不确定字符串的长度,或者需要更大的灵活性,使用VARCHAR可能更合适。

四、日期与时间类型

在前面的文章使用过到data类型。该类型就是属于日期类型的。常见的日期类型有:

  • date:日期格式为 'YYYY-MM-DD',占用三字节。
  • datetime:时间日期格式为 'YYYY-MM-DD HH:MM:SS',占用八字节。
  • timestamp:时间戳,从1970年开始的。格式为 'YYYY-MM-DD HH:MM:SS',占用四字节。

通过上图可以看出,timestamp时间戳是不允许为空的,并且他是有默认值的。默认值就是当前的时间戳。插入数据看一下:

看到并没有插入时间戳时会自动插入和更新的 。这里的更新是指的每当对表进行修改操作时,时间戳就会更新

在使用这些数据类型时,需要根据实际需求选择合适的类型。如果只需要存储日期,选择DATE类型;如果需要存储日期和时间,选择DATETIME或TIMESTAMP类型,根据需要考虑是否需要自动更新功能。TIMESTAMP常用于的就是评论时记录时间或者发表内容时的时间。

五、枚举与集合类型

5.1 enum

enum类型是一种字符串对象的类型,用于定义一个列可以包含的可能值的有限列表。语法:enum('value1', 'value2', ...)。其中,'value1', 'value2'等是列允许的枚举值。我们直接看一个实际的例子。如下图:

当我们再插入数据时,插入hobby属性时,就可以从我们的枚举列表中进行选择其中一个进行插入。如下图:

如上图所示,插入的数据并不是枚举中的属性值,就会报错。出于效率考虑,这些值实际存储的是"数字",因此这些选项的每个选项值依次对应如下数字:1,2,3,...最多65535个;当我们添加枚举值时,也可以添加对应的数字编号(枚举中仍然何以使用下标进行选择所要插入的数据)。如下图:

但是需要注意的一点是:枚举中的第一个元素下标是从1开始的,并不是从0开始的

5.2 set

通过对上述的枚举的理解后,我们发现在很多情况下一个人的爱好会有很多,并不是只有一个。但是枚举类型只能一次选一个。这时候我们就可以使用set类型。

SET是一种字符串对象,用于定义一个列可以包含的可能值的多选列表。语法:SET('value1', 'value2', ...)。其中,'value1', 'value2'等是列允许的多选值。我们可以直接通过之前学的对表进行修改,把hobby的类型改成set。具体如下图

插入一些数据,具体如下图:

通过上图可以看到,再插入数据时我们可以从set集合中一次选多个数据进行插入,也可一次只选一个数据。set集合设定只是提供了若干个选项的值,最终一个单元格中,设计可存储了其中任意多个值;**而且出于效率考虑,这些值实际存储的也是"****数字",因此这些选项的每个选项值依次对应如下数字:1,2,4,8,16,32,...最多64个。我们再来通过数字进行插入,**具体如下图:

【注意】3是1和2相加的结果,7是1和2和4相加的结果。我们可对应set集合进行查看。

虽然可以用数字添加枚举,但是不建议在添加枚举值,集合值的时候采用数字的方式,因为不利于阅读,且后期维护成本较高。

5.3 查找

find_in_set()是 MySQL 中的一个函数,用于在逗号分隔的字符串列表中查找指定的字符串。它的作用是在一个逗号分隔的字符串列表中查找指定的值,并返回该值在列表中的位置。使用方法:

FIND_IN_SET(search_string, string_list)

其中:

  • search_string是要查找的字符串。
  • string_list是逗号分隔的字符串列表,它包含要搜索的多个字符串。

返回值:

  • 如果search_string在string_list中找到,则返回它在列表中的位置(从 1 开始)。
  • 如果未找到,则返回 0。

我们就使用find_in_set()进行查找喜欢篮球的,结果如下图:

当然,也可以在后面跟任何你想筛选的条件。

相关推荐
shyの同学1 小时前
分布式ID生成方案:数据库号段、Redis与第三方开源实现
redis·分布式·mysql·id
月落星还在1 小时前
Redis 的过期策略与键的过期时间设置
数据库·redis·bootstrap
cg50174 小时前
MySQL数据库复杂的增删改查操作
数据库·mysql
虾球xz5 小时前
游戏引擎学习第147天
数据库·学习·游戏引擎
向上的车轮6 小时前
什么是时序数据库?有哪些时序数据库?常见的运用场景有哪些?
数据库·时序数据库
岱宗夫up7 小时前
【Python】Django 中的算法应用与实现
数据库·python·opencv·django·sqlite
比花花解语7 小时前
使用数据库和缓存的时候,是如何解决数据不一致的问题的?
数据库·缓存·数据一致性
YGGP8 小时前
Redis篇:基础知识总结与基于长期主义的内容更新
数据库·redis·缓存
weixin_460783878 小时前
Flutter解决TabBar顶部页面切换导致页面重载问题
android·javascript·flutter
KINICH ahau8 小时前
数据库1-2章
数据库·oracle