你知道 Mysql Varchar 类型为什么人们默认设置 255 吗
前言
为什么 Navicate
默认 varchar
类型是 255
,突然想到了这个问题,并带着疑问去看了一下为什么
Mysql5.6.x
在 Mysql5.6
版本下,单列索引的长度不能超过 767bytes
,联合索引的长度不能超过 3072bytes
CREATE TABLE `test` (
`a` varchar(255) DEFAULT NULL,
`b` varchar(255) DEFAULT NULL,
`c` varchar(255) DEFAULT NULL,
`d` varchar(255) DEFAULT NULL,
`e` varchar(255) DEFAULT NULL,
KEY `a` (`a`,`b`,`c`,`d`,`e`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
> 1071 - Specified key was too long; max key length is 3072 bytes
可以看到,每个字段 255*3*5=3825
,大于了 3072
,则报错了
为什么经常性的设置 varchar 长度为 255
utf8
上面说到单列索引长度为 767
,在 utf8
编码下,一个字符为 3bytes
,那么 255*3=765
,刚好为能够建立索引长度的最大值,如果超出了这个值,如果使用的是 navicat
那么 mysql
会自动将这一列的索引变为前缀索引,截取 255
utf8mb4
在 utf8mb4
下,一个字符为 4bytes
, 那么 767÷4=191.75
,取整为 191
,所以在 utf8mb4
编码下,如果你的 varchar
超出 191
,如果使用的是 navicat
那么 mysql
会自动将这一列的索引变为前缀索引,截取 191
Mysql5.7.x
在 Mysql5.7
版本下,单列索引的长度不能超过 3072bytes
,联合索引的长度不能超过 3072bytes
为什么联合索引长度是 3072
我们知道 InnoDB
一个 page
的默认大小是 16k
。由于是 Btree
组织,要求叶子节点上一个 page
至少要包含两条记录(否则就退化链表了)。
所以一个记录最多不能超过 8k
。
又由于 InnoDB
的聚簇索引结构,一个二级索引要包含主键索引,因此每个单个索引不能超过 4k
(极端情况,pk和某个二级索引都达到这个限制)。
由于需要预留和辅助空间,扣掉后不能超过 3500
,取个 整数
就是 1024*3=3072
。
本作品采用《CC 协议》,转载必须注明作者和本文链接