百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

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

bigegpt 2024-11-18 09:00 4 浏览

在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是指当前字段能放的最大字符数

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

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

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

但实际上是这样吗?我们慢慢分析。。。

虽然通常认为VARCHAR字段的最大长度是65535,但实际上这个说法是不完全准确的。这是因为,在MySQL中,VARCHAR字段的最大长度取决于多个因素,包括字符集、行格式和存储引擎等。下面我们将对这些因素进行详细说明。

一、行格式的影响

MySQL 中的行格式是指在存储数据时,将数据按照一定的方式组织成行的格式。常见的行格式有固定长度行格式(Fixed-length format)和动态行格式(Dynamic format)

在固定长度行格式中,每一行都有固定的长度,每个字段的长度都是固定的。而在动态行格式中,每一行的长度都是根据数据的实际长度而定,字段长度也是根据数据的实际长度来动态调整的。因此,使用不同的行格式,对于 varchar 字段的最大长度有不同的影响。

在固定长度行格式中,varchar 类型字段的最大长度确实是 65535。因为在固定长度行格式中,每个字段都占用固定的空间,varchar 类型字段的长度也是固定的,所以其最大长度是受到限制的。

而在动态行格式中,varchar 类型字段的最大长度是根据实际数据长度而定的,不受到固定长度的限制。因此,在动态行格式中,varchar 类型字段的最大长度可以超过 65535。

示例:

假设我们有一个包含一个 varchar 类型字段的表,行格式为 Dynamic,字符集为 utf8mb4。我们插入一个长度为 80000 的字符串:

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `value` varchar(80000) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

INSERT INTO `test` (`value`) VALUES (REPEAT('a', 80000));

在这个例子中,我们插入了一个长度为 80000 的字符串,而在 Dynamic 行格式下,这个字符串可以被正确地存储,没有出现错误。

二、字符集的影响

MySQL 支持多种字符集,包括 ASCII、ISO-8859、utf8mb4 等。不同的字符集对于 varchar 类型字段的最大长度也有不同的影响。

在 ASCII 和 ISO-8859 字符集中,一个字符只占用一个字节的空间,因此 varchar 类型字段的最大长度是 65535 个字节。而在 utf8mb4 字符集中,一个字符可能占用 1 到 4 个字节的空间,因此 varchar 类型字段的最大长度也就不再是固定的,而是根据字符集的不同而有所不同。

示例:

我们继续以 utf8mb4 字符集为例,考虑长度为 80000 的字符串在 varchar 类型字段中的最大长度。

在 utf8mb4 字符集下,每个字符可能占用的字节数不同,最大为 4 个字节。因此,如果我们使用 utf8mb4 字符集,那么 varchar 类型字段的最大长度是 65535/4=16383

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `value` varchar(16383) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

INSERT INTO `test` (`value`) VALUES (REPEAT('你', 80000));

在这个例子中,我们将 varchar 类型字段的最大长度设为 16383,在 utf8mb4 字符集下,一个字符最多占用 4 个字节,因此这个字段最大能存储的字符串长度为 16383。但是我们插入了一个长度为 80000 的字符串,MySQL 报错:

ERROR 1406 (22001): Data too long for column 'value' at row 1

这是因为插入的字符串长度超过了我们定义的最大长度。

三、存储引擎的影响

MySQL 支持多种存储引擎,包括 InnoDB、MyISAM、Memory 等。不同的存储引擎对于 varchar 类型字段的最大长度也有不同的影响。

在 InnoDB 存储引擎中,varchar 类型字段的最大长度是受到限制的,最大长度为 65535。而在 MyISAM 存储引擎中,varchar 类型字段的最大长度可以达到 65535/2=32767。

示例:

我们以 InnoDB 和 MyISAM 存储引擎为例,分别考虑长度为 80000 的字符串在 varchar 类型字段中的最大长度。

在 InnoDB 存储引擎下,varchar 类型字段的最大长度是受到限制的,最大长度为 65535。因此,在 InnoDB 存储引擎下,我们需要将 varchar 类型字段的长度设为 65535 或更小。

 `id` int(11) NOT NULL AUTO_INCREMENT,
  `value` varchar(65535) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

INSERT INTO `test_innodb` (`value`) VALUES (REPEAT('a', 65535));

在这个例子中,我们将 varchar 类型字段的长度设为 65535,在 InnoDB 存储引擎下,这个字段最大能存储的字符串长度就是 65535。

而在 MyISAM 存储引擎下,varchar 类型字段的最大长度可以达到 65535/2=32767。因此,在 MyISAM 存储引擎下,我们可以将 varchar 类型字段的长度设为 32767 或更小。

CREATE TABLE `test_myisam` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `value` varchar(32767) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;

INSERT INTO `test_myisam` (`value`) VALUES (REPEAT('a', 32767));

在这个例子中,我们将 varchar 类型字段的长度设为 32767,在 MyISAM 存储引擎下,这个字段最大能存储的字符串长度就是 32767。

需要注意的是,在 MySQL 5.7.5 之前的版本中,MyISAM 存储引擎也存在最大行长度的限制,因此即使在 MyISAM 存储引擎下,varchar 类型字段的最大长度也不一定能够达到 65535/2=32767。在 MySQL 5.7.5 之后,MyISAM 存储引擎的最大行长度限制被取消,因此 varchar 类型字段的最大长度可以达到 65535/2=32767。

相关推荐

悠悠万事,吃饭为大(悠悠万事吃饭为大,什么意思)

新媒体编辑:杜岷赵蕾初审:程秀娟审核:汤小俊审签:周星...

高铁扒门事件升级版!婚宴上‘冲喜’老人团:我们抢的是社会资源

凌晨两点改方案时,突然收到婚庆团队发来的视频——胶东某酒店宴会厅,三个穿大红棉袄的中年妇女跟敢死队似的往前冲,眼瞅着就要扑到新娘的高额钻石项链上。要不是门口小伙及时阻拦,这婚礼造型团队熬了三个月的方案...

微服务架构实战:商家管理后台与sso设计,SSO客户端设计

SSO客户端设计下面通过模块merchant-security对SSO客户端安全认证部分的实现进行封装,以便各个接入SSO的客户端应用进行引用。安全认证的项目管理配置SSO客户端安全认证的项目管理使...

还在为 Spring Boot 配置类加载机制困惑?一文为你彻底解惑

在当今微服务架构盛行、项目复杂度不断攀升的开发环境下,SpringBoot作为Java后端开发的主流框架,无疑是我们手中的得力武器。然而,当我们在享受其自动配置带来的便捷时,是否曾被配置类加载...

Seata源码—6.Seata AT模式的数据源代理二

大纲1.Seata的Resource资源接口源码2.Seata数据源连接池代理的实现源码3.Client向Server发起注册RM的源码4.Client向Server注册RM时的交互源码5.数据源连接...

30分钟了解K8S(30分钟了解微积分)

微服务演进方向o面向分布式设计(Distribution):容器、微服务、API驱动的开发;o面向配置设计(Configuration):一个镜像,多个环境配置;o面向韧性设计(Resista...

SpringBoot条件化配置(@Conditional)全面解析与实战指南

一、条件化配置基础概念1.1什么是条件化配置条件化配置是Spring框架提供的一种基于特定条件来决定是否注册Bean或加载配置的机制。在SpringBoot中,这一机制通过@Conditional...

一招解决所有依赖冲突(克服依赖)

背景介绍最近遇到了这样一个问题,我们有一个jar包common-tool,作为基础工具包,被各个项目在引用。突然某一天发现日志很多报错。一看是NoSuchMethodError,意思是Dis...

你读过Mybatis的源码?说说它用到了几种设计模式

学习设计模式时,很多人都有类似的困扰——明明概念背得滚瓜烂熟,一到写代码就完全想不起来怎么用。就像学了一堆游泳技巧,却从没下过水实践,很难真正掌握。其实理解一个知识点,就像看立体模型,单角度观察总...

golang对接阿里云私有Bucket上传图片、授权访问图片

1、为什么要设置私有bucket公共读写:互联网上任何用户都可以对该Bucket内的文件进行访问,并且向该Bucket写入数据。这有可能造成您数据的外泄以及费用激增,若被人恶意写入违法信息还可...

spring中的资源的加载(spring加载原理)

最近在网上看到有人问@ContextConfiguration("classpath:/bean.xml")中除了classpath这种还有其他的写法么,看他的意思是想从本地文件...

Android资源使用(android资源文件)

Android资源管理机制在Android的开发中,需要使用到各式各样的资源,这些资源往往是一些静态资源,比如位图,颜色,布局定义,用户界面使用到的字符串,动画等。这些资源统统放在项目的res/独立子...

如何深度理解mybatis?(如何深度理解康乐服务质量管理的5个维度)

深度自定义mybatis回顾mybatis的操作的核心步骤编写核心类SqlSessionFacotryBuild进行解析配置文件深度分析解析SqlSessionFacotryBuild干的核心工作编写...

@Autowired与@Resource原理知识点详解

springIOCAOP的不多做赘述了,说下IOC:SpringIOC解决的是对象管理和对象依赖的问题,IOC容器可以理解为一个对象工厂,我们都把该对象交给工厂,工厂管理这些对象的创建以及依赖关系...

java的redis连接工具篇(java redis client)

在Java里,有不少用于连接Redis的工具,下面为你介绍一些主流的工具及其特点:JedisJedis是Redis官方推荐的Java连接工具,它提供了全面的Redis命令支持,且...