likes
comments
collection
share

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

作者站长头像
站长
· 阅读数 21

hello,大家好,我是张张,「架构精进之路」公号作者。

写在前面

关于 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 个字节。

  • 在 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 类型

定义如下:

CREATE TABLE t1 (
  c varchar(N) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

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

(65535−1−2)/ 4 = 16383

备注:

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

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

除 2 的原因是字符编码是 utf8mb4。

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

定义如下:

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

那表 t2 的`c`字段的最大长度 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);

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

Column length too big for column 'name' (max = 16383); use BLOB or TEXT instead.

总结一下

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

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

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

·END·

希望今天的讲解对大家有所帮助,谢谢!

Thanks for reading!

作者:张张,十年研发风雨路,大厂架构师,「架构精进之路」专注架构技术沉淀学习及分享,职业与认知升级,坚持分享接地气儿的干货文章,期待与你一起成长。

关注并私信我回复“01”,送你一份程序员成长进阶大礼包,欢迎勾搭。

转载自:https://juejin.cn/post/7389089457733845029
评论
请登录