VARCHAR的长度怎么计算? VARCHAR(255) 与 VARCAHR(256)的区别在哪里?

问题

1、本文旨在阐明一些在解决这些问题过程中感到迷惑的点。
2、笔者的测试环境是 Mysql 5.7 ,引擎是innoDB,采用的编码是UTF-8(每个汉子3个字节)。

  1. varchar()的长度怎么计算?
  2. varchar(255) 与 varchar(256) 的区别在哪里?

解析

varchar()的长度怎么计算?
4.0版本以下,varchar(20),指的是20字节。
5.0版本以上,varchar(20),指的是20字符。

首先明确长度概念,我理解这里涉及的长度应该有四种:字符串的字节长度字符串的字符长度字段的实际长度索引长度(字符串最大长度)

CREATE TABLE test (
    name VARCHAR(100) DEFAULT NULL,
) CHARSET=utf8;
  1. 插入100个汉字。
    各值应为:
    字符串的字节长度: 3 * 100 = 300 字节。Mysql length() 函数可得
    字符串的字符长度: 100个汉字即 100个字符。Mysql char_length() 函数可得
    字段的实际长度: 3 * 100 + 1 + 2 = 303 字节。 其中 1 为 null 标识位,2 为varchar实际长度标识位。
    索引长度(字符串最大长度): 3 * 100 + 1 + 2 = 303 字节。 当字段存满时其值等于字段实际长度。

  2. 插入50汉字50英文。
    各值应为:
    字符串的字节长度: 3 * 50 + 50 = 200 字节。 Mysql length() 函数可得
    字符串的字符长度: 50汉字,50英文即 100个字符。Mysql char_length() 函数可得
    字段的实际长度: 3 * 50 + 50 + 1 + 1 = 202 字节。 其中 1 为 null 标识位,1 为varchar实际长度标识位。
    索引长度(字符串最大长度): 3 * 100 + 1 + 2 = 303 字节。

以上示例可能产生一些疑惑的点在于,两个标识位的算法(null标识位、varchar实际长度标识位)。

对这里有疑惑的同学,建议先看一下 Mysql 行存储 的规则,我在这里仅做一个简单的描述:

null标识位: 每一个允许为空的字段都需要标识它在当前行里是否为空。
具体算法是 (N + 7)/ 8 ,其中N代表该表中允许为空的字段数。
举个例子: 1 字节 = 8 比特位,每个比特位可以用0 / 1来标识一个字段是否为空,即8个比特位就能标识8个字段。
varchar实际长度标识位: Mysql 在读取行记录时,需要知道varchar实际存了多长,才能知道要读出几位数据。1 字节 = 8比特位 ,2 ^ 8 = 256 ,即可以标识 0 ~ 255 ; 2 字节 = 16 比特位 ,2 ^ 16 = 65536 ,即可以标识 0 ~ 65535 ,因此最多仅需要 2 字节位即可标识实际长度。

varchar(255) 与 varchar(256) 的区别在哪里?

之前看到大佬设置 varchar(255) 很好奇有什么用,简单查阅以后得知,256 需要两个标识位,255需要一个标识位,记下以后满意的离去了。
后来探究varchar长度计算方式的时候发现了问题,假如我们设定字段类型为 varchar(255) ,那我存放255个汉字,字符串的字节长度应为 255 * 3 = 765 ,765 是不能用1个字节标识的。
实际上varchar(255)和varchar(256)的区别在于索引,Mysql 5.6 之前 索引最大的长度是 767 字节 。而 767 / 3 ≈ 255 ,正好支持索引的建立。(这个地方属于个人理解,没在老版本验证,有懂的大佬忘及时纠正)

参考资料

三篇博文有一些本人认为描述不太正确的地方,因为没有去翻官网资料,没办法下结论。各位看客自行分辨。
https://blog.csdn.net/yinjinshui/article/details/102496340
https://blog.csdn.net/qq_30336433/article/details/81669957
https://liuchenyang0515.blog.csdn.net/article/details/117524328

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值