业务场景是要拆子表,将所有字段合到主表上,有许多字段都是varchar(128), varchar(255), varchar(256), varchar(512) …
结果碰到了如下问题:
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some
columns to TEXT or BLOBs
查阅后了解到:
MySQL 单表会统计所有字段 column 的长度,累积计算到65535。
所以这个问题的原因是子表字段累加的太多了,字节超出了单表允许的范围。
注:
BLOB和TEXT列不同于varchar字段,列长度信息独立于行长存储,可以达到65535字节真实存储
引发思考:
为什么用varchar(255) 而不是 varchar(256)
可变长度列在评估字段大小时还要考虑存储列实际长度的字节数。
char, varchar类型的值,会有一个长度标识位来存值长度。
当定义varchar长度小于等于255时,长度标识位需要一个字节。当大于255时,长度标识位需要两个字节
以utf-8编码为例,对于varchar(255),每一行所占用的内存就是长度的2 byte + 3 * 255 byte
阿里开发规范:
【强制】varchar是可变长字符串,不预先分配存储空间,长度不要超过5000,如果存储长度大于此值,定义字段类型为text,独立出来一张表,用主键来对应,避免影响其它字段索引效率
参考:
https://galaxyyao.github.io/2019/07/30/MySQL-%E6%B2%A1%E6%9C%89%E5%BF%85%E8%A6%81%E7%9A%84varchar-255-%E9%95%BF%E5%BA%A6%E5%8F%8A%E5%AD%98%E5%82%A8%E6%B1%89%E5%AD%97%E9%97%AE%E9%A2%98%E6%B1%87%E6%80%BB/
版权声明:本文为qq_37084673原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。