【深入浅出MySQL】之数据类型介绍

【深入浅出MySQL】之数据类型介绍

  • MySQL中常见的数据类型一览
  • 为什么需要如此多的数据类型
  • 数值类型
    • BIT(M)类型
    • INT类型
    • TINYINT类型
    • BIGINT类型
    • 浮点数类型
      • float类型
      • DECIMAL(M,D)类型
      • 区别总结
  • 字符串类型
    • CHAR类型
    • VARCHAR(M)类型
  • 日期和时间类型
  • enum和set类型

前言:MySQL是一种广泛使用的关系型数据库管理系统,它提供了多种数据类型供开发者去选择,以此来满足不同的场景。

MySQL中常见的数据类型一览

类别数据类型描述存储范围/长度常见用途
数值类型TINYINT非常小的整数-128 到 127(有符号);0 到 255(无符号)存储小的整数,如状态码(0/1)、年龄等
BITM位类型,M指定位数,默认值1M的范围(1~64)适用于需要存储二进制信息的情况,例如标志位、布尔值数组等。通过使用 BIT 类型,可以更有效地存储和操作位级别的数据。
SMALLINT小整数-32,768 到 32,767(有符号);0 到 65,535(无符号)存储中等范围的整数,如计数器、小范围的ID
MEDIUMINT中等大小的整数-8,388,608 到 8,388,607(有符号);0 到 16,777,215(无符号)存储中等范围的整数,较少使用
INT / INTEGER标准整数-2,147,483,648 到 2,147,483,647(有符号);0 到 4,294,967,295(无符号)存储常用整数,如用户ID、订单号等
BIGINT大整数-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807(有符号)存储大范围整数,如大型系统的ID、计数器
FLOAT单精度浮点数约 ±3.4E+38(7位有效数字)存储近似数值,如价格、科学计算数据
DOUBLE双精度浮点数约 ±1.79E+308(15位有效数字)存储更高精度的近似数值,如金融数据、科学计算
DECIMAL(M,D)定点数(精确小数)M 是总位数,D 是小数位数,例如 DECIMAL(10,2) 存储 8位整数+2位小数存储精确小数,如货币金额(避免浮点误差)
字符串类型CHAR(M)固定长度字符串0 到 255 个字符存储固定长度的字符串,如状态码、性别(‘M’/‘F’)
VARCHAR(M)可变长度字符串0 到 65,535 个字符(取决于字符集和存储引擎)存储可变长度的字符串,如用户名、地址
TINYTEXT短文本字符串最大 255 个字符存储短文本,如备注、小段描述
TEXT标准文本字符串最大 65,535 个字符存储较长的文本,如文章内容、评论
MEDIUMTEXT中等长度文本字符串最大 16,777,215 个字符存储中等长度的文本,如长篇文章
LONGTEXT超长文本字符串最大 4,294,967,295 个字符存储超长文本,如日志文件、JSON 数据
ENUM('value1', 'value2', ...)枚举类型,只能从预定义值中选择一个值最多 65,535 个不同值存储固定选项,如状态(‘active’/‘inactive’)、性别(‘male’/‘female’)
SET('value1', 'value2', ...)集合类型,可以选择多个预定义值(以逗号分隔)最多 64 个不同值存储多选选项,如兴趣(‘reading,swimming’)
日期和时间类型DATE日期1000-01-01 到 9999-12-31存储日期,如生日、注册日期
TIME时间-838:59:59 到 838:59:59存储时间,如一天中的时间点、持续时间
DATETIME日期和时间组合1000-01-01 00:00:00 到 9999-12-31 23:59:59存储完整的日期和时间,如创建时间、更新时间
TIMESTAMP时间戳(从 1970-01-01 00:00:00 UTC 开始)1970-01-01 00:00:00 到 2038-01-19 03:14:07(UTC)存储时间戳,常用于记录数据更新时间(自动更新)
YEAR年份1901 到 2155(4位格式);70 到 69(2位格式,1970-2069)存储年份,如出生年份、发布年份
其他类型BINARY(M)固定长度的二进制字符串0 到 255 个字节存储固定长度的二进制数据,如校验码
VARBINARY(M)可变长度的二进制字符串0 到 65,535 个字节存储可变长度的二进制数据,如小型文件
BLOB二进制大对象最大 65,535 个字节存储二进制数据,如图片、文件
MEDIUMBLOB中等长度的二进制大对象最大 16,777,215 个字节存储中等大小的二进制数据,如较大的文件
LONGBLOB超长二进制大对象最大 4,294,967,295 个字节存储超大二进制数据,如视频文件
JSONJSON 格式数据(MySQL 5.7+ 支持)最大 1GB(受限于存储引擎)存储 JSON 数据,如配置信息、动态字段

为什么需要如此多的数据类型

似乎单一数据类型如字符类型可以存储所有的数据,但事实上,我们需要如此多的数据类型的原因有以下几种:

  • 数据的准确性与合法性需求:有时候我们描述某一个列时,如果这个列只能是整数,而不能出现小数点(如id),此时如果只有字符类型就满足不了需求,而整数类型和浮点数类型的存在就可以有效防止非法的数据进入数据库中。
  • 性能上
    • 空间上:如果只有单一的INT类型的整数,有时候某些列的大小永远不会超过某一个整数值,这个时候使用INT就很浪费空间,所以使用 TINYINT 来存储 0 到 255 范围内的整数比使用 VARCHAR 更节省空间。
    • 时间上:对于数值运算,直接使用数值类型而不是字符串类型进行计算会更加高效。这是因为数值类型可以直接参与算术运算,而字符串则需要先转换成数值形式才能进行相应的操作,这增加了额外的处理开销。
  • 功能上
    • 日期时间处理:专门的日期时间类型(如 DATE, TIME, DATETIME)提供了丰富的函数支持,方便进行日期计算、格式化输出等操作。如果用字符串表示日期时间,则需要手动编写代码来进行这些操作,不仅复杂而且容易出错。
  • 查询优化:
    • 索引利用:某些数据类型允许创建特定类型的索引(如全文索引适用于 TEXT 类型),从而提高查询能力。如果所有数据都以字符串形式存储,则可能无法充分利用这些高级索引功能。

数值类型

BIT(M)类型

BIT是位类型,其中M是位数,如果你想精确控制该列的位数,可以使用这个类型。

  1. 创建一个表tt1,表中有一个num列,它的类型是BIT(1)

    image-20250323160326121

  2. 表创建成功了:

    image-20250323160352415

  3. 向表中插入数据:

    image-20250323160647744

    • 超过1就插入失败,因为bit位的位数位1,只能表示01
    • 但是发现一个很奇怪的现象,就算查表,1没有显示出来。
  4. 这是因为bit类型是默认是按照ASCII码,1对应的符号是不可显示的特殊符号。

    image-20250323161104285

  5. 测试一下bit类型位数的边界情况:

    create table tt3(num bit(65));
    create table tt4(num bit(0));
    

    image-20250323161255461

[!tip]

如果我们有一些列,只需要0或者1就可以使用bit(1),这样非常节省空间。

INT类型

INT类型的范围:-2,147,483,648 到 2,147,483,647(有符号);0 到 4,294,967,295(无符号)

这和我们C语言中的是相符的。

但C语言中溢出后会截断,数据库是否会这样呢?

  1. 首先我们创建表tt4

    create table tt4(num int);
    
  2. 查看表tt4:

    image-20250323162142786

    • int后面的数字的含义:这是表示的默认宽度,通常配合ZEROFILL属性使用,这个后面我们再谈,和C语言中的printf的格式控制符很像。
  3. 插入一个数字,我们测试int的边界,插入21474836472,147,483,648,-2,147,483,648 -2,147,483,649

    image-20250323215634411

TINYINT类型

TINYINT也是整数类型,但是它只能表示-128 到 127(有符号),0 到 255(无符号)当你的列需要一个整数类型来表示,但是不会超过255时就可以使用这个类型。

  1. 创建表tt5

    create table tt5(num tinyint);
    
  2. 越界测试:

    insert into tt5 values(128);
    

    image-20250323220704189

BIGINT类型

大整数类型,它能表示-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807(有符号),适合做大型系统的id列的类型、计数器等。

  1. 创建表tt6

    create table tt6(num bigint);
    
  2. 数据类型边界测试:

    insert into tt6 values(-9223372036854775808);
    

    image-20250323221222211

浮点数类型

float类型

语法(syntax)

float[(m, d)] [unsigned] : M指定显示长度,d指定小数位数,占用空间4
  1. 创建表tt7,它有一个num列是float(5,2)类型,长度为5,小数位数为2,它可以表示999.99 ~ -999.99的值:

    create table tt7(float(5,2));
    
  2. 插入一些值观察现象:

    mysql> insert into tt7 values(999.99999999);
    ERROR 1264 (22003): Out of range value for column 'num' at row 1
    mysql> insert into tt7 values(999.99);
    Query OK, 1 row affected (0.00 sec)mysql> insert into tt7 values(999.93);
    Query OK, 1 row affected (0.00 sec)mysql> insert into tt7 values(-999.999);
    ERROR 1264 (22003): Out of range value for column 'num' at row 1
    mysql> insert into tt7 values(-999.99);
    Query OK, 1 row affected (0.00 sec)mysql> insert into tt7 values(-9999);
    ERROR 1264 (22003): Out of range value for column 'num' at row 1
    mysql> insert into tt7 values(-99);Query OK, 1 row affected (0.00 sec)
    mysql> select * from tt7;
    +---------+
    | num     |
    +---------+
    |  999.99 |
    |  999.93 |
    | -999.99 |
    |  -99.00 |
    +---------+
    • 可以看到依旧会发生越界的情况。
  3. 如果我们插入的值长度超过M,但是范围又在此时[M,d]所限定的范围内,就会发生四舍五入的情况:

    image-20250323222356706

DECIMAL(M,D)类型

M 是总位数,D 是小数位数,例如 DECIMAL(10,2) 存储 8位整数+2位小数

听上去好像和float没什么区别呀,我们来建个表插入数据看看:

  1. 创建表tt8,它有一列num,数据类型为decimal(5,2),存储3位整数+2位小数:

    create table tt8(num decimal(5,2));
    
  2. 插入一些值,然后观察现象:

    insert into tt8 values(999.976)
    ...
    

    image-20250323223540971

  • 它似乎也和float一样也会进行越界判断,也会四舍五入,那它们有什么区别呢?

区别总结

我们从实际的现象来观察并思考为什么会这样。

  1. 创建表tt9

    create table tt9(num1 float(10,1),num2 decimal(10,1));
    
  2. 插入下面的值:

    insert into tt9(999999998,999999998);
    
  3. 表中最终的结果:

    mysql> select * from tt9;
    +--------------+-------------+
    | num1         | num2        |
    +--------------+-------------+
    | 1000000000.0 | 999999998.0 |
    +--------------+-------------+
    
    • 居然!,num1被近似成了1000000000.0 ,而且总长度是11位,我们不是规定了总长度吗?这个num2是正常显示的。
  4. 我们手动插入一下一行让num11000000000.0,看能否成功:

    mysql> insert into tt9 values(1000000000.0,999999998);
    ERROR 1264 (22003): Out of range value for column 'num1' at row 1
    
    • 很明显失败了,MySQL报错了。

总结

  • FLOAT 是近似类型:它不保证精确存储和显示,可能会对大数值进行近似处理。
  • DECIMAL 是精确类型:它严格按照定义的范围和精度存储和显示数据。
  • 显示宽度不受严格限制:FLOAT(M,D) 的定义主要用于限制存储范围(也就是限制用户的),但实际显示的宽可能会因为近似超出定义的范围。

所以如果我们的列对数据的精确性要求很高,且是浮点数,就需要使用DECIMAL类型。

字符串类型

CHAR类型

语法:char(L):固定长度字符串,不管用户输入的字符串的长度为多少,MySQL都会拿出L的长度给该列,L的最大值是255

[!caution]

MySQL里面的一个长度就对应一个字符,不管你是中文、英文字符、还是特殊字符都只占一个长度单位,也就是说MySQL对于字符长度有自己的标准。在 MySQL 中,字符长度单位指的是字符的数量,而不是字节数。但是,实际占用的存储空间取决于字符集。

下面我们创建表,插入一些值来验证一下:

  1. 创建表tt10

    create table tt10(s char(5));
    
  2. 插入一些字符:

    insert into tt10 values('你好世界呀');
    insert into tt10 values('abcde');
    insert into tt10 values('abcdef');
    

    image-20250323230740596

  • 我们都知道实际上中文字符的存储字节和英文字符的存储字节一般是不同的,要看具体的存储编码,所以在 MySQL 中,字符长度单位指的是字符的数量,而不是字节数。

[!caution]

如果你插入的字符的长度比L小,MySQL会自动填充空格。

VARCHAR(M)类型

varchar(L): 可变长度字符串,L表示字符长度,最大长度65535个字节

  1. 创建表tt11

    create table tt11(s varchar(10));
    
  2. 插入一些字符串:

    insert into tt11 values("111");
    insert into tt11 values("1111111111");
    

    image-20250324172213459

[!caution]

变长并不是这个类型存储的字符的长度可以超过用户指定的长度L,而是当用户实际存储的字符长度没有L时,MySQL不会使用空格填充,这样节省了空间。

如何选择charvarchar类型

  1. 如果指定列的字符串长度是固定的,就使用char类型。
  2. 当存储大量可变长度的字符串时,可以使用varchar来节省存储空间。
  3. CHAR 因为是定长的,存储和检索效率更高,尤其是在频繁访问和更新的场景中。
  4. VARCHAR 因为需要额外的长度信息,存储和检索效率略低,但在现代数据库系统中,这种差异通常不明显。

日期和时间类型

MySQL中日期类型(如 DATEDATETIMETIMESTAMP 等)是非常重要的数据类型。它们的存在是为了更高效地存储、查询和操作与时间相关的数据。

日期类型可以表示广泛的日期范围,远超过普通字符串或数字能表达的范围。例如:

  • DATE 类型支持从 ‘1000-01-01’ 到 ‘9999-12-31’ 的日期。
  • DATETIMETIMESTAMP 支持精确到秒甚至微秒的时间点。

下面我们创建一个表,使用一下日期类型:

  1. 创建表tt12

    create table tt12(d1 date,d2 datetime,t timestamp);
    
  2. 插入一些值:

    insert into tt12 values('1922-01-22','1922-01-22 00:00:00',FROM_UNIXTIME(1));
    
    • TIMESTAMP 不支持直接插入原始的 Unix 时间戳(如 1742947200),需要通过 FROM_UNIXTIME() 函数进行转换。插入当前时间:可以使用 NOW()CURRENT_TIMESTAMP 来插入当前时间。

    • DATETIME存储日期和时间。

    • DATE只存储日期。

      image-20250324174151354

enum和set类型

ENUM(枚举)类型是一种字符串对象,其值范围必须来自一个预定义的列表。这些值是按定义顺序排列的,并且只能选择列表中的值之一。

SET 类型是一种字符串对象,它可以包含零个或多个由逗号分隔的值,这些值来自于一个预定义的列表。与 ENUM 不同的是,SET 允许一个字段包含多个值。

使用介绍:

  1. 创建表tt13

    create table tt13(identity enum('学生','老师','工人'), set permissions('write','read','exec'));
    
  2. 插入一些值:

    mysql> insert into tt13 values('学生','write,res');
    ERROR 1265 (01000): Data truncated for column 'permissions' at row 1
    mysql> insert into tt13 values('学生','write,read');
    Query OK, 1 row affected (0.00 sec)mysql> insert into tt13 values('学生','write');
    Query OK, 1 row affected (0.00 sec)mysql> insert into tt13 values('学生,老师','write');
    ERROR 1265 (01000): Data truncated for column 'identity' at row 1
    mysql> insert into tt13 values('学生1','write');
    ERROR 1265 (01000): Data truncated for column 'identity' at row 1

    image-20250324174923450

应用场景

  • 使用 ENUM
    • 当字段的值是单一选项时。
    • 需要确保数据一致性且选项数量较少。
    • 场景示例:性别、状态、分类等。
  • 使用 SET
    • 当字段的值是多个选项的组合时。
    • 需要灵活的多选功能且选项数量较少。
    • 场景示例:权限、兴趣爱好、标签等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/78441.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字化时代下,软件测试中的渗透测试是如何保障安全的?

在如今数字化与信息化的时代,软件测试中存在渗透测试,其位置十分重要,它借助模拟恶意攻击的方式,去发现软件系统所存在的漏洞以及安全问题,这是保障软件安全的关键环节,接下来我会对它的各个方面进行详细介…

Pytorch - Developer Notes 1/2

文章目录 自动混合精度示例典型的混合精度训练处理未缩放梯度梯度裁剪 处理缩放梯度梯度累积梯度惩罚 处理多个模型、损失函数和优化器多 GPU 工作环境下的注意事项单进程中的DataParallel分布式数据并行:每个进程对应一个GPU每个进程使用多块GPU的DistributedDataP…

RuntimeError: CUDA error: __global__ function call is not configured

表明在 CUDA 设备上调用的核函数 没有正确配置线程块和网格维度。 一般体现在: 直接调用 kernel 函数,而不是通过 launch 函数 指定 kernel 函数调用 解决方法(示例): // kernel function __global__ void Idtest_k…

cloudfare+gmail 配置 smtp 邮箱

这里介绍有一个域名后,不需要服务器,就可以实现 cloudfare gmail 的 邮箱收发。 为什么还需要 gmail 的 smtp 功能,因为 cloudfare 默认只是对 email 进行转发,就是只能收邮件而不能发送邮件,故使用 gmail 的功能来进…

如何在 CentOS 7 命令行连接 Wi-Fi?如何在 Linux 命令行连接 Wi-Fi?

如何在 CentOS 7 命令行连接 Wi-Fi?如何在 Linux 命令行连接 Wi-Fi? 摘要 本教程覆盖如何在多种 Linux 发行版下通过命令行连接 Wi-Fi,包括: CentOS 7、Ubuntu、Debian、Arch Linux、Fedora、Alpine Linux、Kali Linux、OpenSU…

基于PHP的在线编程课程学习系统

有需要请加文章底部Q哦 可远程调试 基于PHP在线编程课程学习系统 一 介绍 在线编程课程学习系统基于原生PHP开发,数据库mysql,前端jquery.js。系统角色分为学生,教师和管理员。(附带参考设计文档) 技术栈:phpmysqljquery.jsphps…

PyTorch_张量形状操作

搭建模型时,数据都是基于张量形式的表示,网络层与层之间很多都是以不同的shape的方式进行表现和运算。 对张量形状的操作,以便能够更好处理网络各层之间的数据连接。 reshape 函数的用法 reshape 函数可以再保证张量数据不变的前提下改变数…

大模型实践:图文解锁Ollama在个人笔记本上部署llm

使用在线模型服务时,我们常常需要支付API调用费用,这对于个人开发者或小型组织来说可能是一笔不小的开支。那么,有没有方法可以在本地免费使用这些强大的模型呢?答案是肯定的——Ollama就是这样一个工具。 当然如果是比较大的组织…

Python基本语法(lambda表达式)

lambda表达式 lambda的一般形式是在关键字lambda后面跟一个或多个参数,之后再紧跟一个 冒号,接下来是一个表达式。lambda是一个表达式,而不是一个语句,它能够出现 在Python语法不允许def出现的地方。作为表达式,lambd…

【MySQL数据库】用户管理

目录 1,用户信息 2,创建/删除/修改用户 3,数据库的权限 MySQL数据库安装完之后,我们最开始时使用的都是 root 用户,其它用户通常无法进行操作。因此,MySQL数据库需要对用户进行管理。 1,用户…

Python的ArcPy基于Excel表格对大量遥感影像批量重分类

本文介绍基于Python中的ArcPy模块,以Excel表格内的信息,对遥感影像加以重分类的方法。 首先,明确一下本文的需求。现有按照文章ArcPy批量将栅格文件的属性表导出为Excel表格的方法(https://blog.csdn.net/zhebushibiaoshifu/artic…

LabVIEW 中VI Server导出 VI 配置

该 LabVIEW VI 展示了在 VI Server 中配置和执行 Exported VIs 的过程,实现对服务器端导出 VI 的远程调用与操作。 ​ 具体过程及模块说明 前期配置:需确保在 LabVIEW 的 “Tools> Options > VI Server > Protocols” 路径下,启用 …

论文阅读:2024 ACM SIGSAC Membership inference attacks against in-context learning

总目录 大模型安全相关研究:https://blog.csdn.net/WhiffeYF/article/details/142132328 Membership inference attacks against in-context learning https://arxiv.org/pdf/2409.01380 https://www.doubao.com/chat/4030440311895554 速览 这篇论文主要研究了…

从 Python 基础到 Django 实战 —— 数据类型驱动的 Web 开发之旅

主题简介: 本主题以 Python 基础数据类型为核心,结合 Django 框架的开发流程,系统讲解如何通过掌握数字、字符串、列表、元组、字典等基础类型,快速构建功能完善的 Web 应用。通过理论与实践结合,帮助学员从零基础 Py…

软考 系统架构设计师系列知识点之杂项集萃(53)

接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(52) 第85题 在静态测试中,主要是对程序代码进行静态分析。“数据初始化、赋值或引用过程中的异常”属于静态分析中的()。 A. 控制流分析 B. 数据…

Raycaster光线投射

Raycaster光线投射 3D虚拟工厂在线体验 描述 光线投射Raycaster,用于进行raycasting(光线投射)。 光线投射用于进行鼠标拾取(在三维空间中计算出鼠标移过了什么物体)。 构造器 Raycaster( origin : Vector3, dire…

初识Linux —— git三板斧

版本控制器git 为了我们方便管理不同版本的文件,就有了版本控制器; 所谓的版本控制器,就是能够了解到一个文件的历史记录(修改记录);简单来说就是记录每一次的改动和版本迭代的一个管理系统,同…

用哈希表封装出unordered_set/_map

前提: ①:本博客是对哈希表(开散列)进行封装,因为闭散列不优秀(与库保持一致) ②:哈希表封装出unordered_set/_map和红黑树封装出ste/map是大同小异的,可以先看下:用红黑树封装出set和map -CSDN博客 ③&…

情绪ABC——AI与思维模型【93】

一、定义 情绪ABC思维模型是一种心理学上的理论,它认为人们的情绪和行为反应(C,Consequence)并非直接由激发事件(A,Activating event)引起,而是由个体对激发事件的认知和评价所产生…

Unity URP RenderTexture优化(二):深度图优化

目录 前言: 一、定位深度信息 1.1:k_DepthStencilFormat 1.2:k_DepthBufferBits 1.3:_CameraDepthTexture精度与大小 1.4:_CameraDepthAttachment数量 二、全代码 前言: 在上一篇文章:Un…