MySQL数据类型之VARCHAR和CHAR使用详解
在设计数据库字段时,字符串类型算是最常见的数据类型之一了,这篇文章带大家深入探讨一下MySQL数据库中VARCHAR
和CHAR
数据类型的基本特性,以及它们之间的区别。
VARCHAR类型
VARCHAR
(Variable Character,可变长度字符)是一种用于存储可变长度字符串的数据类型,可指定存储数据的最大长度。
VARCHAR
是存储字符串最广泛使用的数据类型之一。在定义VARCHAR
字段时,通常使用VARCHAR(n)
格式指定该字段的最大字符容量,其中n
是允许存储的字符最大数量。
每个VARCHAR
字段可以设置一个最大长度值,从1到65535字符(根据MySQL的存储引擎和行格式限制)。不过,该长度会受到一些因素的影响,例如:
- 表的字符集会影响字段的最大字节数。例如,在一个
utf8mb4
表中,每个字符可能占用最多4字节,因此要确保总长度(包括所有列和其它数据)适配MySQL的行存储限制。 - 行存储限制约为65535字节,因此要在表中合理设计列类型。
由于VARCHAR
是一种可变长度类型,数据库会根据实际存储的字符串长度动态分配足够的存储空间,而不是预先分配最大限定长度的空间。除了存储字符串内容外,还会存储一些额外的元数据。
VARCHAR
数据类型使用额外的长度指示字节存储字符串的长度:
- 如果字符串长度小于255字节(一个
VARCHAR
列的定义最大长度为255字符),则使用1个字节来记录长度; - 如果字符串长度超过255字节,则需要2个字节来记录长度。
CHAR类型
CHAR
是MySQL中的一种字符数据类型,最大长度为255个字符,主要用于存储固定长度的字符串。无论插入的数据是否达到了定义的长度,CHAR
都会根据其设定的长度自动填充空格(使用空格补齐),以确保其值总是固定长度。它适用于那些长度固定的、不经常变化的字符串,比如国家代码、省份缩写等。
当一个列的类型定义为CHAR
类型后,列中的内容的长度就是字段定义的长度(字符数)。如果写入CHAR
列中的字符串的长度小于指定的字符长度,MySQL会在源字符串后填充空格一直到指定的长度。当读取CHAR
列中的值时,MySQL会删除后面的空格。
由于CHAR
数据类型采用固定的长度进行存储,因此CHAR
的性能要比VARCHAR
更好。
与VARCHAR
类似,可以使用CHAR(n)
格式来设置字段的最大字符数。如果未指定,n
默认为1。在CHAR
列中存储的值会右对齐用空格填充,因此不管要保存的字符串内容如何,它始终会存储n
个字符。
字符集对字段存储的影响
在数据库设计中,字符集 (Character Set) 和排序规则 (Collation) 是重要的环节。字符集决定了可以存储哪些字符以及每个字符所需的空间,而排序规则决定了数据如何比较和排序。
数据库在日常使用中,除了要支持英文字符之外,还需要支持像西班牙语中的特殊字符 “Ñ”,以及像日语中的 “データベース” 或中文中的 “数据库” 等复杂字符。为此,MySQL提供了多种字符集(charset
),如 latin1
(用于基本英文字符)、utf8
(支持大部分语言)、utf8mb4
(支持完整的 Unicode,包括表情符号)。
字符集不仅影响文本在数据库中的存储形式,也直接影响该字段的存储空间效率。不同字符集的每个字符所需的字节数不同,具体如下:
latin1
: 每个字符固定占用 1 个字节。utf8
: 每个字符占用 1~3 个字节。utf8mb4
: 每个字符占用 1~4 个字节(主要用于完整的 Unicode,例如表情符号)。
在使用VARCHAR
字段时,定义的最大长度n
指的是字符的数量,而不是具体存储所需的字节数。由于字符集影响每个字符的数据大小,因此实际存储时需要考虑字符占用的字节数以及MySQL的行存储限制。
MySQL中,每行数据的最大存储限制为65,535 字节,这包括所有列的数据以及其他额外信息(如长度字节、行偏移量等)。
字符集对CHAR
类型的影响与VARCHAR
类型类似,但由于CHAR
是固定长度存储,影响的性质稍有不同。CHAR
无论存储的字符数量是多少,总会为字段定义的最大长度分配固定空间。例如,在utf8mb4
下,一个CHAR(255)
字段最大可能需要255 × 4 = 1,020字节。
由于CHAR
是固定长度存储类型,在多字节字符集下往往存在空间浪费问题,因此在合理选择字段数据类型时,需要结合应用场景、字符集及数据特性来做对应的设计。
数据可视化的差异
当数据存储到CHAR
字段时,其副作用之一是字符串中的所有尾随空格会在保存时被忽略。实际查询时,MySQL不会返回这些尾随空格,因为它会假设这些空格仅仅是数据类型的填充部分。
用具体的实例演示一下,创建一个表,其中有两个列:VARCHAR(20)
和CHAR(20)
。接下来插入一些尾部有5个空格的数据,并观察它们的存储情况。
CREATE TABLE strings(id INT PRIMARY KEY AUTO_INCREMENT,variable VARCHAR(20),fixed CHAR(20)
);INSERT INTO strings (variable, fixed) VALUES ("Drifter ", "Drifter ");
如果运行以下SELECT
语句,表面上看返回的数据是相同的:
SELECT * FROM strings;
但如果使用CHAR_LENGTH
函数来计算每个字段实际使用的字符数,就会发现差异。VARCHAR
字段(用varchar_data_length
表示)显示为12,其中包括结尾的5个空格字符,而CHAR
字段仅显示为7。
这是因为MySQL存储了VARCHAR
值末尾的空格,但认为CHAR
值的末尾空格只是填充,因此忽略了这一部分数据。
SELECT CHAR_LENGTH(variable) AS varchar_data_length, CHAR_LENGTH(fixed) AS char_data_length FROM strings;
字段存储空间示例
当数据写入磁盘时,VARCHAR
值会有额外的开销。如果存储字符串 “Spider”(长度为6个字符)到VARCHAR(6)
和CHAR(6)
的字段中,以utf8mb4
字符集为例,以下是磁盘空间消耗情况:
VARCHAR
值占用25字节(每字符4字节 + 1字节开销)。CHAR
值占用24字节(每字符4字节,无额外开销)。
如果存储字符串 “Eido” 到这些字段,以下结果会发生变化:
VARCHAR
只使用17字节,因为它是可变长度。CHAR
保持使用24字节,因为它是固定长度且右填充了2个空格。
字段存储对照表如下:
值 | VARCHAR(6) 存储值 | VARCHAR(6) 使用空间 | CHAR(6) 存储值 | CHAR(6) 使用空间 |
---|---|---|---|---|
“Spider” | “Spider” | 25 字节 | “Spider” | 24 字节 |
“Eido” | “Eido” | 17 字节 | "Eido " | 24 字节 |
"Eido " | "Eido " | 25 字节 | "Eido " | 24 字节 |
小结
最后,总结一下本文的关键点:
- VARCHAR特点:可变长度,适用于存储长度不固定的字符串,并且根据实际数据长度动态分配空间。
- CHAR特点:固定长度,有性能优势,但可能导致存储空间浪费,适用于长度固定的字符串。
- 字符集影响:字符集决定了每个字符的字节数,以及存储时所需的空间大小,如utf8mb4需要1~4字节。
- 数据存储差异:VARCHAR保留尾部空格且会增加长度指示字节,CHAR填充尾部空格但在查询时忽略。
- 空间消耗对比:VARCHAR更节省空间,但有附加开销;CHAR采用固定空间,适合少量数据且不受字符长度变化影响。
在数据库设计中,VARCHAR和CHAR是两种常见的字符串存储类型,它们各有适用场景和性能特点。在选择字段类型时,应充分考虑数据的变化形态、存储性能和空间效率。
相关文章:

MySQL数据类型之VARCHAR和CHAR使用详解
在设计数据库字段时,字符串类型算是最常见的数据类型之一了,这篇文章带大家深入探讨一下MySQL数据库中VARCHAR和CHAR数据类型的基本特性,以及它们之间的区别。 VARCHAR类型 VARCHAR(Variable Character,可变长度字符…...
数字人 LAM 部署笔记
目录 windos踩坑 GitHub - aigc3d/LAM: [SIGGRAPH 2025] LAM: Large Avatar Model for One-shot Animatable Gaussian Head windos踩坑 nvidia-smi环境 cuda 11.8conda install -c "nvidia/label/cuda-11.8.0" cuda-toolkit conda create --name cuda11.8 -y pyth…...

《Docker 入门与进阶:架构剖析、隔离原理及安装实操》
1 docker 简介 1.1 Docker 的优点 Docker 是一款开放平台,用于应用程序的开发、交付与运行,能将应用和基础架构分离,实现软件快速交付 ,还能以统一方式管理应用和基础架构,缩短代码从编写到上线的时间。其核心优势如…...

基于Akamai云计算平台的OTT媒体点播转码解决方案
点播视频(VOD)流媒体服务依赖于视频流的转码来高效分发内容。在转码工作流程中,视频被转换为适合观看设备、网络条件和性能限制的格式。视频转码是计算密集型过程,因此最大化可用硬件上可转码的视频流数量是首要考虑因素。不同基础…...

【MySQL】02.数据库基础
1. 数据库的引入 之前存储数据用文件就可以了,为什么还要弄个数据库? 文件存储存在安全性问题,文件不利于数据查询和管理,文件不利于存储海量数据,文件在程序中控制不方便。而为了解决上述问题,专家们设计出更加利于…...

选错方向太致命,华为HCIE数通和云计算到底怎么选?
现在搞HCIE的兄弟越来越多了,但“数通和云计算,到底考哪个?”这问题,依旧让不少人头疼。 一个是华为认证的老牌王牌专业——HCIE数通,稳、系统、岗位多; 一个是新趋势方向,贴合云原生、数字化…...

经典启发算法【早期/启发式/HC爬山/SA模拟退火/TS禁忌搜/IA免疫 思想流程举例全】
文章目录 一、早期算法二、启发式算法三、爬山法HC3.1 基本思路3.2 伪代码 四、模拟退火SA4.1 算法思想4.2 基本流程4.3 再究原理4.3.1 Metropolis准则4.3.2 再理解 4.4 小Tips4.5 应用举例4.5.1 背包问题:分析:求解: 4.5.2 TSP问题ÿ…...

IntraWeb 16.0.2 + Bootstrap 4 居中布局实战(附源码+效果图)
前言 最近在优化一个 IntraWeb 16.0.2 项目时,发现默认布局方式不够灵活,尤其是在不同屏幕尺寸下对齐效果不佳。于是,我决定引入 Bootstrap 4 来实现 完美居中布局,并成功落地!今天就把完整的 源代码 实际效果图 分享…...
Spring 框架中适配器模式的五大典型应用场景
Spring 框架中适配器模式的应用场景 在 Spring 框架中,适配器模式(Adapter Pattern)被广泛应用于将不同组件的接口转化为统一接口,从而实现组件间的无缝协作。以下是几个典型的应用场景: 1. HandlerAdapter - MVC 请…...

【Java ee初阶】jvm(3)
一、双亲委派机制(类加载机制中,最经常考到的问题) 类加载的第一个环节中,根据类的全限定类名(包名类名)找到对应的.class文件的过程。 JVM中进行类加载的操作,需要以来内部的模块“类加载器”…...
C 语言多维数组:定义、初始化与访问的深度解析
各类资料学习下载合集 https://pan.quark.cn/s/8c91ccb5a474 在 C 语言中,我们已经熟悉了一维数组(存储线性数据)和二维数组(存储表格或矩阵数据)。但现实世界的数据结构往往更加复杂,例如表示空间中的点、图像数据、物理模拟的网格等。这时,就需要用到多维数…...
浅入ES5、ES6(ES2015)、ES2023(ES14)版本对比,及使用建议---ES6就够用(个人觉得)
JavaScript(ECMAScript)的发展经历了多个版本,每个版本都引入了新特性和改进。以下仅是对三个常用版本(ES5、ES6(ES2015) 和 ES2023)的基本对比及使用建议: 目前常见项目中还是用ES6…...

23种设计模式考试趋势分析之——适配器(Adapter)设计模式——求三连
文章目录 一、考点分值占比与趋势分析二、真题考点深入挖掘三、"wwwh"简述四、真题演练与解析五、极简备考笔记 适配器模式核心要点六、考点记忆顺口溜七、多角度解答 一、考点分值占比与趋势分析 由于知识库提供的真题年份信息不完整,我们仅能对现有数据…...
Python 翻译词典小程序
一、概述 本工具是基于Python开发的智能翻译系统,采用有道词典进行翻译,并具有本地词典缓存以及单词本功能。 版本号:v1.0 (2025-05-15) 二、核心功能说明 1. 基础翻译功能 即时翻译:输入英文单词自动获取中文释义 词性识别&…...

【Linux笔记】——线程互斥与互斥锁的封装
🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:Linux 🌹往期回顾🌹:【Linux笔记】——Linux线程封装 🔖流水不争,争的是滔滔不息 一、线程互斥的概念二、互…...

Android屏幕采集编码打包推送RTMP技术详解:从开发到优化与应用
在现代移动应用中,屏幕采集已成为一个广泛使用的功能,尤其是在实时直播、视频会议、远程教育、游戏录制等场景中,屏幕采集技术的需求不断增长。Android 平台为开发者提供了 MediaProjection API,这使得屏幕录制和采集变得更加简单…...

【深度学习】残差网络(ResNet)
如果按照李沐老师书上来,学完 VGG 后还有 NiN 和 GoogLeNet 要学,但是这两个我之前听都没听过,而且我看到我导师有发过 ResNet 相关的论文,就想跳过它们直接看后面的内容。 现在看来这不算是不踏实,因为李沐老师说如果…...

《Python星球日记》 第94天:走近自动化训练平台
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、自动化训练平台简介1. Kubeflow Pipelines2. TensorFlow Extended (TFX) 二…...

S7 200 smart连接Profinet转ModbusTCP网关与西门子1200PLC配置案例
控制要求:使用MODBUSTCP通信进行两台PLC之间的数据交换,由于改造现场不能改动程序,只留出了对应的IQ地址。于是客户决定使用网关进行通讯把数据传到plc。 1、读取服务器端40001~40005地址中的数据,放入到VW200~VW208中࿱…...
React中巧妙使用异步组件Suspense优化页面性能。
文章目录 前言一、为什么需要异步组件?1. 性能瓶颈分析2. 异步组件的价值 二、核心实现方式1. React.lazy Suspense(官方推荐)2. 路由级代码分割(React Router v6) 总结 前言 在 React 应用中,随着功能复…...

学习笔记:黑马程序员JavaWeb开发教程(2025.4.7)
12.9 登录校验-Filter-入门 /*代表所有,WebFilter(urlPatterns “/*”)代表拦截所有请求 Filter是JavaWeb三大组件,不是SpringBoot提供的,要在SpringBoot里面使用JavaWeb,则需要加上ServletComponentScan注…...
11 web 自动化之 DDT 数据驱动详解
文章目录 一、DDT 数据驱动介绍二、实战 一、DDT 数据驱动介绍 数据驱动: 现在主流的设计模式之一(以数据驱动测试) 结合 unittest 框架如何实现数据驱动? ddt 模块实现 数据驱动的意义: 通过不同的数据对同一脚本实现…...

OpenCV-python灰度变化和直方图修正类型
实验1 实验内容 该段代码旨在读取名为"test.png"的图像,并将其转换为灰度图像。使用加权平均值法将原始图像的RGB值转换为灰度值。 代码注释 image cv.imread("test.png")h np.shape(image)[0] w np.shape(image)[1] gray_img np.zeros…...
从 Excel 到 Data.olllo:数据分析师的提效之路
背景:Excel 的能力边界 对许多数据分析师而言,Excel 是入门数据处理的第一工具。然而,随着业务数据量的增长,Excel 的一些固有限制逐渐显现: 操作容易出错,难以审计; 打开或操作百万行数据时&…...

图像定制大一统?字节提出DreamO,支持人物生成、 ID保持、虚拟试穿、风格迁移等多项任务,有效解决多泛化性冲突。
字节提出了一个统一的图像定制框架DreamO,支持人物生成、 ID保持、虚拟试穿、风格迁移等多项任务,不仅在广泛的图像定制场景中取得了高质量的结果,而且在适应多条件场景方面也表现出很强的灵活性。现在已经可以支持消费级 GPU(16G…...

Nginx 动静分离在 ZKmall 开源商城静态资源管理中的深度优化
在 B2C 电商高并发场景下,静态资源(图片、CSS、JavaScript 等)的高效管理直接影响页面加载速度与用户体验。ZKmall开源商城通过对 Nginx 动静分离技术的深度优化,将静态资源响应速度提升 65%,带宽成本降低 40%…...

在vs code 中无法运行npm并报无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查
问题: npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查 原因: 可能是环境变量未正确继承或终端配置不一致 解决方法: 1.找到自己的node.js的版本号 2.重新下载node.js 下载 node.js - https://nodejs.p…...

分布式2(限流算法、分布式一致性算法、Zookeeper )
目录 限流算法 固定窗口计数器(Fixed Window Counter) 滑动窗口计数器(Sliding Window Counter) 漏桶算法(Leaky Bucket) 令牌桶算法(Token Bucket) 令牌桶与漏桶的对比 分布式…...
2089. 找出数组排序后的目标下标——O(n)做法!
本题要求在一个已排序的数组 nums 中,找出所有等于目标值 target 的元素下标。若不存在这样的元素,则返回 {-1, -1}。解决该问题有两种主要方法:二分查找法和统计计数法。 二分查找法:首先对数组进行排序,然后通过二分…...

ARM A64 LDR指令
ARM A64 LDR指令 1 LDR (immediate)1.1 Post-index1.2 Pre-index1.3 Unsigned offset 2 LDR (literal)3 LDR (register)4 其他LDR指令变体4.1 LDRB (immediate)4.1.1 Post-index4.1.2 Pre-index4.1.3 Unsigned offset 4.2 LDRB (register)4.3 LDRH (immediate)4.3.1 Post-index…...