面试官:说一说mysql的varchar字段最大长度?

news2025/6/18 8:39:01

在mysql建表sql里,我们经常会有定义字符串类型的需求。

CREATE TABLE `user` (
  `name` varchar(100) NOT NULL DEFAULT '' COMMENT '名字'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ;

比方说user表里的名字,就是个字符串。mysql里有两个类型比较适合这个场景。

char和varchar。

声明它们都需要在字段边上加个数组,比如char(100)varchar(100),这个100是指当前字段能放的最大字符数

char和varchar的区别在于,varchar虽然声明了最大能放100个字符,但一开始不需要分配100个字符的空间,可以根据需要慢慢增加空间。而char一开始声明是多少,就固定预留多少空间。

所以,varchar比起char更省空间,一般没啥大事,大家都爱用varchar

那问题来了,声明varchar字段时,它的最大长度是多少呢?

相信大家应该听说过varchar字段的最大长度是65535吧。

没听过也没关系,你现在听到了。

但实际上是这样吗?

我们来做个实验。

varchar最大值是多少

我们直接拿65535来试一下。

长度为65535的varchar报错

很明显报错了。

报错内容也说了, 由于列长度过大导致报错,最长是16383

把上面的65535改成 16383,确实是成功了。

哦?所以说varchar最大值是16383?

当然不是。

这其实还有好几个因素影响这这个最大值。

不同字符集的影响

varchar里放的是字符串,而字符串看起来可以是英文字母,也可以是数字或中文。但不管怎么样,都可以把这样的中英文数字转成二进制的01串。

按照一定规则把符号和二进制码对应起来,这就是编码。而把n多这种已经编码的字符聚在一起,就是我们常说的字符集

建表语句里有个CHARSET,这里填的是字符集。

不同的字符集要求使用的字节个数也不同,我们可以通过 show charset; 看到mysql支持哪些字符集,以及这些字符集里存储一个字符所需的最大字节数(Maxlen)。

查看mysql支持哪些charset

我们尝试下把建表sql语句里的CHARSET改一改,比如改成utf8mb3

我们再执行下,会发现,最大值又不一样了。

utf8mb3下的报错

并且,上面虽然提示max=21845,但要是真执行起来会发现还是报错。在改为21844之后才成功。

不讲武德。

再把字符集改为 latin1。会发现,最大值会是 65533

varchar为65533时创建成功

这里渐渐可以发现规律。

  • utf8mb4的maxlen=4,对应varchar最大长度=16383。4*16383 = 65532。

  • utf8mb3的maxlen=3,对应varchar最大长度=21844。3*21844 = 65532。

  • latin1的maxlen=1,对应varchar最大长度=65533。   1 * 65533 = 65533。

也就是说varchar边上的长度代表的是这一列能放的最大字符数,而maxlen代表单个字符占用的最大字节数。相乘的结果很接近65535。说明65535是指的字节数,而不是字符数

也就是说varchar的最大长度,根据选择的字符集的不同,会有区别。

总的来说接近于 65535 除以 字符集的maxlen。

但其实这样还不够严谨。还有其他影响因素。

是否可以为NULL的影响

上面的建表语句里声明了test字段都是NOT NULL,也就是非空,如果我们将这个改成可以为NULL,再用 CHARSET=latin1去试试。这时候就会发现,前面NOT NULL的时候最大能使用65533去建表,现在报错了。

改成65532,就能成功了,也就是最长长度少了1个字节

是否为NULL的影响

这是因为一个字段是否为NULL这件事情,是需要一个字节去记录下来的。

而当字段为NOT NULL的时候,则可以省下这个字节。

列数的影响

上面提到的情况都是在表里只有一列时的结果,当我们表里有更多的列时,我们会发现varchar的最大值还会有变化。比如同样还是latin1字符集,我们再增加一列varchar类型,并且用的还是前面允许的最大值65533。

结果发现这次会失败。

两个varchar列的情况

查了一下资料发现,原来65535是mysql单行的最大长度(不包含blob和text等类型的情况下)

mysql表里单行中的所有列加起来(不考虑其他隐藏列和记录头信息) ,占用的最大长度是65535个字节。

注意上面加粗的部分,加起来不超过65535。

比如如果还有int的列,那它占用4个字节,bigint占用8个字节,字段越多,留给单个varchar列的空间就越少。

因此,前面提到的 varchar 的最大长度,接近于 65535 除以 字符集的maxlen,但前提是只有一列not null 的varchar类型的字段。

为什么不是65535而是65533?

不过问题又来了,上面建表sql里,不管是那种字符集,最后得到的字符数都约等于65533。

但数据库单行最大值应该是65535。65535 - 65533 = 2 。这里面还差了个2,为什么呢?

这就要聊一下mysql单行里数据到底是怎么存储的。

数据表行存储的格式

我们可以通过 show table status 命令,查看到当前表格使用的行格式。

查看到当前表格使用的行格式

通过上面的 Row_format 字段可以看到这个表用的是 Dynamic 行格式。

事实上,现在的mysql数据表一般都是采用Dynamic行记录格式。

我们来看下Dynamic行格式长什么样子。

Dynamic行记录格式

Dynamic格式将行记录分为两部分,分为是行记录的额外信息行记录的真实数据

行记录的额外信息:

  • 变长字段长度列表:指的是varchar,text,blob这种类型,它们属于变长字段,这里表示的就是这些字段的长度。

  • NULL值列表:用来记录当前行里哪些列是为null的。如果全部列都是not null的话,那就不需要有这个字段。

  • 记录头信息:这是固定5个字节,用来记录一些特殊的信息,比如这一行是否被删了,这一行在这个16k的数据页内是不是最小的,以及指向下一条记录的指针之类的一些信息,不需要太关注。

行记录的真实数据:

里面放的就是一行里,每一列的真正内容。除了我们建表时里涉及到的列以外,还有一些隐藏列。

比如Row_ID,这个是在建表是没有声明主键时,数据表自动会生成的隐藏主键。另外还有trx_id字段,用于记录当前这一行数据行是被哪个事务修改的,和一个roll_pointer字段,这个字段是用来指向当前这个数据行的上一个版本,通过这个字段,可以为这行数据形成一条版本链,从而实现多版本并发控制(MVCC)。有没有很眼熟,这个在之前写的文章里出现过。

隐藏列有哪些

所以我们回过头来看我们建的表,当只有一列not null的 varchar字段时,行记录长下面这样。

单条varchar数据的Dynamic行记录格式.drawio

前面提到,行最大值65535字节是不包含隐藏列和记录头信息的,所以其实是指上图中红色的部分。

而最左边的变长字段长度列表中,为了表示varchar列的长度,占用了两个字节,也就是16位,2的16次方,最大可以表示65535的长度,正好足够用来表示varchar列当前的长度是65533。

所以65535 - 65533 = 2 。这里面差的2,是用来存varchar字段长度去了。

一个页才16k,怎么保存65533(64k)数据?

之前的文章里其实多次提到了mysql底层是以页的形式去存储数据的,而一个页固定16k,而一个varchar字段最大能放65533字节数据,换算一下大概是64k,整整4个16k的页。

页结构

这里面是怎么实现的?

对于这种情况,其实行数据里针对这个超大的varchar字段只保存个20字节的指针(实际上是个偏移量),这个指针会指向新的页(off page),这些页里保存的是实际的varchar字段里的65533字节数据。这种由于字段过长导致需要额外的页来保存数据的现象叫行溢出

行溢出

大于64k的字符串该怎么处理?

如果离谱点,数据量更大,比64k还大,这时候就不能继续用varchar了,需要改用text和blob类型字段。

而text和blob类型本身也是分TINY、MEDIUM,LONG三个档位的,对应着不同的数据长度,最大到4G左右。

像下面这样就可以将数据类型定义为LONGTEXT。

CREATE TABLE `test_max_length` (
  `test` LONGTEXT NOT NULL COMMENT '测试长度字段'
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;

而他们的存储方式也跟varchar的情况类似,只保存20个字节的指针,实际数据保存在其他溢出页里。

以前我们查某一行数据,他们都在一个16k的数据页里,查询时只要一次磁盘IO就能将这个数据页读取出来。

当一个数据库里某行数据里有个特别大的字符串时,我们如果还想把整行数据给读出来,那我们还得把off page的数据给全部读出来,这意味着更多的磁盘IO,性能就更差了

为了规避这个问题,我们写select sql的时候,如果发现某列字段,是个特别长的字符串时,能不读它就尽量不加到select里,这也是为什么大家不建议使用select * from table的原因。

blob和text的区别

一般来说,blob和text都可以用来放超长字符串。但它们会有一点点区别。

我们知道字符集(charset)下还有个校对规则(collation)的概念,比如同样是a,大写A和小写a能不能算作是一个字符,这会影响比较和排序,collation就是定义这个规则用的。

blob没有字符集的概念,而text有。这意味如果用blob来存文本的话,就没法用字符集的校对规则来排序和做比较。

还有一个区别,blob还能保存二进制数据,比如压缩过的文本数据,图片或者视频,别笑,虽然不合适,但我确实见过有人拿它来保存视频。。。

总结

  • 现在的mysql数据表一般采用Dynamic行记录格式。它由行记录的额外信息和行记录的真实数据组成。

  • mysql表里单行中的所有列加起来(不考虑其他隐藏列和记录头信息) ,占用的最大长度是65535个字节。

  • 如果数据表里只有一列 not null 的varchar字段,它的最大长度,接近于 65535 除以 字符集的maxlen

  • 如果要存放大于64k的字段数据,可以考虑使用longtext和longblob等类型。

  • mysql的数据页大小是16k,为了保存varchar或者text,blob这种长度可能大于16k的字段,在Dynamic行格式中,会只保留20个字节的指针,实际数据则放在其他溢出页中。为了将它们读取出来,会需要更多的磁盘IO。

  • blob和text很像,但blob没有字符集的概念,并且还能存放二进制的数据,比如图片或视频,但实际上图片和视频更推荐放在对象存储(Object Storage Service,简称oss)中。

原文:mysql的varchar字段最大长度真的是65535吗?

作者:小白debug

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

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

相关文章

剧本拆分如何用ai人工智能辅助完成

随着现代技术的发展,人工智能在电影制作领域中的应用已经越来越普遍。其中,辅助剧本拆分是人工智能技术的一种重要应用。人工智能可以帮助电影制作人员更快速、更准确地进行剧本拆分,提高制作效率和创作质量。 剧本拆分是电影制作中非常重要的…

二叉树的链式结构

思维导图 二叉树的创建 先定义一个二叉树链式结构的结构体 typedef int BTDatatype; typedef struct BinaryTreeNode {struct BinaryTreeNode* left;struct BinaryTreeNode* right;BTDatatype data; }BTNode; 手搓一个二叉树(前序遍历的方式创建二叉树放到OJ题…

nm命令 以及 C++11 编译出现找不到stringstream 以及 undefined reference to `std::runtime_error

最近在学习ZLMediaKit 源码 里面用到了很多C11 的知识 本地有一个 ubuntu18.04 的服务器 源码下下来发现 直接编译报很多错误 比如 找不到 std::runtime_error 找不到 stringstream 等等等 后来偶然的机会发现 是libstdc.so.6 太老了 找一个新的 替换掉这个就可以 …

新 Nano(五)自己写个库,读 DHT11 / DHT22

DHT11 这款温湿度传感器 几乎是所有 MCU 入门第一个传感器, 现在看来有些不合时宜, 毕竟过于廉价,数据不太靠谱,远不如 AHT10 好用。早年买了两个,按例程读出数据后就吃灰了。某日看到有人说自己按datasheet去读&#…

c#快速入门~在java基础上,知道C#和JAVA 的不同即可

☺ 观看下文前提:如果你的主语言是java,现在想再学一门新语言C#,下文是在java基础上,对比和java的不同,快速上手C#,当然不是说学C#的前提是需要java,而是下文是从主语言是java的情况下&#xff…

CloudIDE 如何提升研发效能

原文作者:行云创新技术总监 邓冰寒 引言 CloudIDE ,一种基于云计算技术开发的云原生集成开发环境,可以帮助企业提高研发效能,实现数字化转型的目标。本文将探讨 CloudIDE 如何在数字化时代体现业务价值、提升研发效能。 CloudID…

【一起撸个DL框架】1 绪论

文章目录第一章 绪论 🍉1.1 在人工智能的大潮里1.2 为什么重复造轮子1.3 深度学习框架简介第一章 绪论 🍉 1.1 在人工智能的大潮里 人工智能——一个如今十分火热的话题,人们在生活中越来越多地使用它、谈论它。在2022年之前,人…

ChatGPT会取代律师这份职业吗?

如今,一种新型的人工智能威胁再次来袭,律师们可能会感到似曾相识的感觉。有人警告称,类似于ChatGPT的软件,因为具有类似于人类的语言流畅性,可能会取代大部分法律工作。 人工智能​的进步曾让人们预测,法律…

Linux 网络扫描工具:nmap,涨知识的时间到了!

在Linux系统中,nmap是一个非常流行的网络扫描工具。它可以用于探测主机和网络上的开放端口、操作系统类型、服务和应用程序等信息。nmap还可以与Ping命令结合使用,以便快速识别网络上的活动主机。本文将介绍如何在Linux上使用nmap和Ping命令进行扫描。 …

服务器部署需要注意的事项

前言:相信看到这篇文章的小伙伴都或多或少有一些编程基础,懂得一些linux的基本命令了吧,本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python:一种编程语言&…

在win10系统中使用EasyUEFI修复​Win10+Ubuntu双系统​引导启动项

我安装了Win10Ubuntu双系统,有一天电脑突然坏了开不了机,把硬盘拆下放到别的机器上,发现是直接进入Win10系统,而不是grub选择界面。进F12也找不到ubuntu的启动项。 之前网上的修复方法是: 1. 首先你需要一张ubuntu的…

多智能体强化学习论文导读

Adaptive Value Decomposition with Greedy Marginal Contribution Computation for Cooperative Multi-Agent Reinforcement Learning Dec-POMDP 本文的研究对象是 decentralized partially observable Markov decision process (Dec-POMDP), 我们首先来看一下它和经典的MDP…

用HTTP proxy module配置一个而反向代理服务器

反向代理与正向代理 摘抄:https://cloud.tencent.com/developer/article/1418457 正向代理 正向代理(forward proxy):是一个位于客户端和目标服务器之间的服务器(代理服务器),为了从目标服务器取得内容,…

2023-04-11 无向图的匹配问题

无向图的匹配问题 之所以把无向图的这个匹配问题放到最后讲是因为匹配问题借鉴了有向图中一些算法的思想 1 最大匹配和完美匹配 二分图回顾 二分图:把一个图中的所有顶点分成两部分,如果每条边的两端分别属于不同部分,则这个图是二分图。更多…

银行数字化转型导师坚鹏:金融科技与数字化转型成功案例

金融科技与数字化转型成功案例课程背景: 数字化转型背景下,很多银行存在以下问题: 不清楚金融科技如何赋能数字化转型? 不清楚银行金融科技体系的建设情况? 不了解银行数字化转型标杆成功案例? 课程特色…

AD六层板布线经验累积

目录 1、布局: 2、创建电源类PWR 3、高速部分可以加屏蔽罩, 4、EMMC和NANDFLASH采取兼容放置(创建联合) 5、HDMI设计 6、就近原则摆放 7、AV端口 8、模拟信号(1字型或L型走线) 9、WIFI模块 10、局…

Python+ChatGPT实战之进行游戏运营数据分析

文章目录一、数据二、目标三、解决方案1. DAU2. 用户等级分布3. 付费率4. 收入情况5. 付费用户的ARPU最近ChatGPT蛮火的,今天试着让ta写了一篇数据分析实战案例,大家来评价一下!一、数据 您的团队已经为您提供了一些游戏数据,包括…

考研数二第十七讲 反常积分与反常积分之欧拉-泊松(Euler-Poisson)积分

反常积分 反常积分又叫广义积分,是对普通定积分的推广,指含有无穷上限/下限,或者被积函数含有瑕点的积分,前者称为无穷限广义积分,后者称为瑕积分(又称无界函数的反常积分)。 含有无穷上限/下…

基于粒子群优化算法的分布式电源选址与定容【多目标优化】【IEEE33节点】(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

接口自动化测试面试常问的题目及答案,你都会了吗?

目录 前言 接口自动化测试的优势是什么? 你使用过哪些接口自动化测试工具? 你如何设计一个接口自动化测试用例? 接口自动化测试中常见的测试类型有哪些? 你如何解决接口自动化测试中遇到的问题? 如何进行接口自动…