VARCHAR(M) 到底占用多少个字节?|MySQL系列(2)
作者 | 小汪哥写代码
来源 | 小汪哥(ID:xwgcoding)
前言
这个问题其实很有迷惑性,问的是字节,不是字符,我们知道在计算机中只能存储二进制数据。所以要搞清楚这个问题?就要搞清楚下面2个问题:
1.字节和字符的对应关系。
2.varchar 到底能存多少个字节。
为了搞清楚上面两个问题,又必须搞清楚mysql 的字符集 和比较规则,以及mysql记录的存储结构。这里我们都是以常用的InnoDB引擎为讨论的前提的。
如果你了解了上面的问题,你也可以回答下面的问题
1.乱码问题是怎么产生的呢?
2.mysql 有时候为什么不区分大小写?
字符集和排序规则
计算机中的的落盘存储都是二进制数据:即bit。所以我们存储字符串的话就要建立字符与二进制数据的映射关系了。
将一个字符映射成一个二进制数据的过程也叫做编码,将一个二进制数据映射到一个字符的过程叫做解码。mysql抽象出一个概念来描述某个字符范围的编码规则 ,这个概念就叫 字符集。
比如:
字符范围:
'a'、'b'、'A'、'B'。
编码规则:
'a' -> 00000001 (十六进制:0x01)
'b' -> 00000010 (十六进制:0x02)
'A' -> 00000011 (十六进制:0x03)
'B' -> 00000100 (十六进制:0x04)
那么字符串 'bA' 可以表示为:
'bA' -> 0000001000000011 (十六进制:0x0203)
对于比较规则,就是数据哪个放前面哪个放后面的问题。对于某一种字符集来说,比较两个字符大小的规则可以制定出很多种,也就是说同一种字符集可以有多种比较规则。
常用字符集
如上图所示5.7.22版本一共支持41种字符集 ,Default collation 表示 字符集默认比较规则。Maxlen代表该种字符集表示一个字符最多需要几个字节。
这个时候就可以回答2个问题了。
- 还记得我们上一篇《执行sql 语句时发生了什么?|mysql 系列(1)》讲到的客户端和服务端通信的那张图吗?客户端和服务器设置不同字符集时,如果编码和解码使用的字符集不一致,就会产生乱码。
- 如果比较规则中同一个大小写的比较规则是相等的,那么就不会区分大小写了。
好了,那我们现在知道VARCHAR(M) 到底占用多少个字符 就和mysql 设置的字符集有关系了。
所以下面我们看看VARCHAR(M)落到物理磁盘到底占用多少个字节,用字符集的Maxlen * M 就能得到 字节数了。这就是答案了。
现在我们引申出另外一个问题,varchar 最大能保存多少个字节呢?这个我们下次讨论。