关于MySQL varchar类型最大值,原来一直都理解错了

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 关于MySQL varchar字段类型的最大值计算,也许我们一直都理解错误了,本文从问题出发,经实践验证得出一些实用经验,希望对大家的开发工作有些帮助~

写在前面


关于MySQL varchar字段类型的最大值计算,也许我们一直都理解错误了,本文从问题出发,经实践验证得出一些实用经验,希望对大家的开发工作有些帮助~


背景描述


最近同事在做技术方案设计时候,考虑到一个表设计时希望利用varchar类型进行存储,而不是采用text,那就需要确定下varchar允许的最大长度是多少,用来评估下后期是否会遇到存储长度瓶颈。


那问题来了:MySQL 数据库的varchar字段类型最大存储长度到底是多少?


问题分析


一切以官方文档为准,翻了下官方描述如下:

In MySQL 4.1 the length is always 1 byte. In MySQL 5.0 the length may be either 1 byte (for up to 255) or 2 bytes (for 256 to 65535).


大概意思就是说:


  • 在MySQL 4.1以前,长度总是1个字节(varchar(20),指的是20字节


  • 在MySQL 5.0以后,长度可以是1字节(最多255个字节)或2个字节(256到65535)


按照官网说法最大值是65535bytes,utf8mb4编码情况下每个字符占4个bytes,最大值应该为16383.75


65535/4=16383.75


实践验证


到此貌似已经有了结论了,但实际情况真的是这样的么?


我们来实验下试试看?

mysql 版本:
select version(); // 5.7


1、若一个表只有一个varchar类型


定义如下:

CREATETABLE`t1` (  
  `c`varchar(N) DEFAULTNULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


那表 t1 的`c`字段的最大长度N为多少呢?


(65535−1−2)/4=16383


备注:

· 减1的原因是实际行存储从第二个字节开始;

· 减2的原因是varchar头部的2个字节表示长度;

· 除4的原因是字符编码是utf8mb4。


2)若表中包含其他多种类型的情况呢


定义如下:

CREATETABLE`t2` (
  `c1`int(10) DEFAULTNULL,
  `c2`char(32) DEFAULTNULL,
  `c3`varchar(N) DEFAULTNULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


那表 t2 的`c3`字段的最大长度N为多少呢?


(65535−1−2−4−32*4)/4=16350


备注:

· 减1、减2的原因同上;

· 减4的原因是int类型占用4个字节;

· 减32*4的原因是utf8mb4编码的char类型占用4个字节(长度32)


我们来验证一下是否如上述推断计算所述:


1)修改t2表`c3`字段长度为16350


alter table `t2` modify column `c3` varchar(16350);


执行成功。


2)修改t2表`c3`字段长度为16351


alter table `t2` modify column `c3` varchar(16351);


执行失败,报错信息如下:


Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs.


总结一下


Q:varchar到底能存多少个字符?


A:这与表使用的字符集相关,latin1、gbk、utf8、utf8mb4编码存放一个字符分别需要占1、2、3、4个字节,同时还要考虑到去除其他字段的占用影响。


实践出真知,可以简单试一下之后再下结论。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
17天前
|
关系型数据库 MySQL
用dbeaver创建一个enum类型,并讲述一部分,mysql的enum类型的知识
这篇文章介绍了如何在DBeaver中创建MySQL表的枚举(ENUM)字段,并探讨了MySQL中ENUM类型的一些行为特点,例如ENUM值的默认排序和在插入重复值时的表现。
29 1
用dbeaver创建一个enum类型,并讲述一部分,mysql的enum类型的知识
|
1月前
|
关系型数据库 MySQL 数据库
Python MySQL查询返回字典类型数据的方法
通过使用 `mysql-connector-python`库并选择 `MySQLCursorDict`作为游标类型,您可以轻松地将MySQL查询结果以字典类型返回。这种方式提高了代码的可读性,使得数据操作更加直观和方便。上述步骤和示例代码展示了如何实现这一功能,希望对您的项目开发有所帮助。
83 4
|
4月前
|
分布式计算 DataWorks MaxCompute
DataWorks产品使用合集之需要将mysql 表(有longtext类型字段) 迁移到odps,但odps好像没有对应的类型支持,该怎么办
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
5月前
|
Oracle 关系型数据库 MySQL
实时计算 Flink版操作报错之在处理MySQL的DECIMAL类型时出现了报错,是什么原因
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
1月前
|
自然语言处理 算法 Java
Java如何判断两句话的相似度类型MySQL的match
【9月更文挑战第1天】Java如何判断两句话的相似度类型MySQL的match
23 2
|
2月前
|
存储 关系型数据库 MySQL
MySQL bit类型增加索引后查询结果不正确案例浅析
【8月更文挑战第17天】在MySQL中,`BIT`类型字段在添加索引后可能出现查询结果异常。表现为查询结果与预期不符,如返回错误记录或遗漏部分数据。原因包括索引使用不当、数据存储及比较问题,以及索引创建时未充分考虑`BIT`特性。解决方法涉及正确运用索引、理解`BIT`的存储和比较机制,以及合理创建索引以覆盖各种查询条件。通过`EXPLAIN`分析执行计划可帮助诊断和优化查询。
|
2月前
|
缓存 NoSQL Redis
一天五道Java面试题----第九天(简述MySQL中索引类型对数据库的性能的影响--------->缓存雪崩、缓存穿透、缓存击穿)
这篇文章是关于Java面试中可能会遇到的五个问题,包括MySQL索引类型及其对数据库性能的影响、Redis的RDB和AOF持久化机制、Redis的过期键删除策略、Redis的单线程模型为何高效,以及缓存雪崩、缓存穿透和缓存击穿的概念及其解决方案。
|
2月前
|
关系型数据库 MySQL 数据管理
深入解析 MySQL 中的关系类型
【8月更文挑战第31天】
38 0
|
3月前
|
存储 关系型数据库 MySQL
Mysql有布尔(BOOL)类型吗
Mysql有布尔(BOOL)类型吗
472 0
|
3月前
|
存储 关系型数据库 MySQL