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

news2025/5/10 3:53:19

【深入浅出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.coloradmin.cn/o/2372005.html

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

相关文章

Vue3响应式:effect作用域

# Vue3响应式: effect作用域 什么是Vue3响应式? 是一款流行的JavaScript框架,它提供了响应式和组件化的视图组织方式。在Vue3中,响应式是一种让数据变化自动反映在视图上的机制。当数据发生变化时,与之相关的视图会自动更新。 作用…

25.5.4数据结构|哈夫曼树 学习笔记

知识点前言 一、搞清楚概念 ●权:___________ ●带权路径长度:__________ WPL所有的叶子结点的权值*路径长度之和 ●前缀编码:____________ 二、构造哈夫曼树 n个带权值的结点,构造哈夫曼树算法: 1、转化成n棵树组成的…

RabbitMQ 深度解析:从核心组件到复杂应用场景

一.RabbitMQ简单介绍 消息队列作为分布式系统中不可或缺的组件,承担着解耦系统组件、保障数据可靠传输、提高系统吞吐量等重要职责。在众多消息队列产品中,RabbitMQ 凭借其可靠性和丰富的特性,在企业级应用中获得了广泛应用。 二.RabbitMQ …

【Linux笔记】系统的延迟任务、定时任务极其相关命令(at、crontab极其黑白名单等)

一、延时任务 1、概念 延时任务(Delayed Jobs)通常指在指定时间或特定条件满足后执行的任务。常见的实现方式包括 at 和 batch 命令,以及结合 cron 的调度功能。 2、命令 延时任务的命令最常用的是at命令,第二大节会详细介绍。…

使用阿里AI的API接口实现图片内容提取功能

参考链接地址:如何使用Qwen-VL模型_大模型服务平台百炼(Model Studio)-阿里云帮助中心 在windows下,使用python语言测试,版本:Python 3.8.9 一. 使用QVQ模型解决图片数学难题 import os import base64 import requests# base 64 …

从零开始搭建你的个人博客:使用 GitHub Pages 免费部署静态网站

🌐 从零开始搭建你的个人博客:使用 GitHub Pages 免费部署静态网站 在互联网时代,拥有一个属于自己的网站不仅是一种展示方式,更是一种技术能力的体现。今天我们将一步步学习如何通过 GitHub Pages 搭建一个免费的个人博客或简历…

C#串口通信

在C#中使用串口通信比较方便,.Net 提供了现成的类, SerialPort类。 本文不对原理啥的进行介绍,只介绍SerialPort类的使用。 SerialProt类内部是调用了CreateFile,WriteFile等WinAPI函数来实现串口通信。 在后期的Windows编程系…

服务器配置llama-factory问题解决

在配置运行llama-factory,环境问题后显示环境问题。这边给大家附上连接,我们的是liunx环境但是还是一样的。大家也记得先配置虚拟环境。 LLaMA-Factory部署以及微调大模型_llamafactory微调大模型-CSDN博客 之后大家看看遇到的问题是不是我这样。 AI搜索…

Spring Boot + Vue 实现在线视频教育平台

一、项目技术选型 前端技术: HTML CSS JavaScript Vue.js 前端框架 后端技术: Spring Boot 轻量级后端框架 MyBatis 持久层框架 数据库: MySQL 5.x / 8.0 开发环境: IDE:Eclipse / IntelliJ IDEA JDK&…

使用Jmeter进行核心API压力测试

最近公司有发布会,需要对全链路比较核心的API的进行压测,今天正好分享下压测软件Jmeter的使用。 一、什么是Jmeter? JMeter 是 Apache 旗下的基于 Java 的开源性能测试工具。最初被设计用于 Web 应用测试,现已扩展到可测试多种不同的应用程…

JavaScript中数组和对象不同遍历方法的顺序规则

在JavaScript中,不同遍历方法的顺序规则和适用场景存在显著差异。以下是主要方法的遍历顺序总结: 一、数组遍历方法 for循环 • 严格按数组索引顺序遍历(0 → length-1) • 支持break和continue中断循环 • 性能最优,…

redis----通用命令

文章目录 前言一、运行redis二、help [command]三、通用命令 前言 提示:这里可以添加本文要记录的大概内容: 学习一些通用命令 以下操作在windows中演示 提示:以下是本篇文章正文内容,下面案例可供参考 一、运行redis 我们先c…

IntelliJ IDEA 保姆级使用教程

文章目录 一、创建项目二、创建模块三、创建包四、创建类五、编写代码六、运行代码注意 七、IDEA 常见设置1、主题2、字体3、背景色 八、IDEA 常用快捷键九、IDEA 常见操作9.1、类操作9.1.1、删除类文件9.1.2、修改类名称注意 9.2、模块操作9.2.1、修改模块名快速查看 9.2.2、导…

Comfyui 与 SDwebui

ComfyUI和SD WebUI是基于Stable Diffusion模型的两种不同用户界面工具,它们在功能、用户体验和适用场景上各有优劣。 1. 功能与灵活性 ComfyUI:ComfyUI以其节点式工作流设计为核心,强调用户自定义和灵活性。用户可以通过连接不同的模块&…

WiseAD:基于视觉-语言模型的知识增强型端到端自动驾驶——论文阅读

《WiseAD: Knowledge Augmented End-to-End Autonomous Driving with Vision-Language Model》2024年12月发表,来自新加坡国立和浙大的论文。 在快速发展的视觉语言模型(VLM)中,一般人类知识和令人印象深刻的逻辑推理能力的出现&a…

探索SQLMesh中的Jinja宏:提升SQL查询的灵活性与复用性

在数据工程和数据分析领域,SQL是不可或缺的工具。随着项目复杂度的增加,如何高效地管理和复用SQL代码成为了一个重要课题。SQLMesh作为一款强大的工具,不仅支持标准的SQL语法,还引入了Jinja模板引擎的宏功能,极大地提升…

对Redis组件的深入探讨

目录 1、磁盘和内存 1.1、概念 1.2、区别 1.3、联系 2、redis基本特性 2.1、数据结构 2.2、性能 2.3、事件驱动架构 2.4、原子性 3、redis模型 3.1、单线程 3.2、事件驱动模型 3.3、epoll多路复用 4、数据持久化 4.1、RDB快照 4.2、AOF(Append Only…

Uni-app 组件使用

在前端开发领域,能够高效地创建跨平台应用是开发者们一直追求的目标。Uni-app 凭借其 “一次开发,多端部署” 的特性,成为了众多开发者的首选框架。而组件作为 Uni-app 开发的基础单元,合理运用组件能够极大地提升开发效率和代码的…

嵌入式学习笔记 - STM32 SRAM控制器FSMC

一 SRAM控制器内部结构图: 以下以512K SRAM芯片为例 二 SRAM地址矩阵/寻址方式: SRAM的地址寻址方式通过行地址与列地址交互的方式存储数据 三 STM32 地址映射 从STM32的地址映射中可以看出,FSMC控制器支持扩展4块外部存储器区域&#xff0…

数据封装的过程

数据的封装过程 传输层 UDP 直接将数据封装为UDP数据报​,添加UDP头部(8B)。 要点: UDP首部简单,无连接不可靠、无重传、无拥塞控制,适用于实时性要求较高的通讯;不需要源端口或不想计算检…