● MySQL Server最多只允许4096个字段
● InnoDB 最多只能有1000个字段
● 字段长度加起来如果超过65535,MySQL server层就会拒绝创建表
● 字段长度加起来(根据溢出页指针来计算字段长度,大于40的,溢出,只算40个字节)如果超过8126,InnoDB拒绝创建表
其实MySQL在计算字段长度的时候并不是按照字段的全部长度来记的。列字段小于40个字节的都会按实际字节计算,如果大于20 * 2=40 字节就只会按40字节。
创建一个300个字段长度类型为varchar(30)的表,在创建时不会创建成功。因为varchar(30)没有超过20*2,那么总长度就是300*30=9000 > 8126就会创建失败。
创建一个150个字段长度类型为varchar(100)的表可以创建成功。因为varchar(100) 大于了20*2那么就只会按40计算 总长度就是150*20*2=6000 < 8126 就会创建成功。
varchar(40) uft8 理论上能建立203列(8126/40) 但是实际上只建立了 196列
● 表结构中根据Innodb的ROW_FORMAT的存储格式确定行内保留的字节数(20 VS 768),最终确定一行数据是否小于8126,如果大于8126,报错。
MySQL官方手册就可以查询到, 对于一行记录最大的限制是65535字节。为什么是65535?规定一行数据里面字段长度定义有64k;
有了65535的限制以后还有一个8126的限制是为什么呢?
MySQL是分两层的,
MySQL Server层 + 存储引擎层。
第2个问题其实是MySQL除了在Server层做了一次限制还会在Innodb存储引擎层在做一次限制。
innodb为了保证B+TREE是一个平衡树结构,强制要求一条记录的大小不能超过一个页大小的一半。这也就是我们上面看到的第二个错误。
下面是innodb B+树的结构,我们可以想象一下二分查找时,一个页的只有一条数据会是什么样子?
每个页只有一条数据的查找就变成了链表查找了。这样就没有二分查找的意义了。
而MySQL中默认的页大小是16K,16K的一半是8196字节减去一些元数据信息就得出了8126这个数字。