在设置 M 的大小时,起决定作用的并不是 M 的有效值范围(0 ~ 65535),而是 M * 字符集的最大字节数不能超过65535个字节。
为什么不能超过 65535 字节呢?
因为MySQL限制了一条记录的最大长度就是 65535 字节
除此之外,对于VARCHAR,在实际设置时,还需考虑以下两个因素:
1. MySQL需要1 ~ 2个字节来表示字符串的长度。具体来说,如果字符串占用的字节数在 0 ~255 之间,需1个字节来表示,如果大于 255 个字节,则需2个字节来表示。
2. 如果列定义为NULL,额外还需要1个字节。
既然 65535 是记录的最大长度,则这个限制不仅仅是针对一列,而是所有列。即所有列的长度加起来不能超过65535。
• 注意,上面提到的一条记录的最大长度不能超过65535字节是MySQL的服务层限制,与存储引擎无关。实际上,存储引擎对行长也有限制。在InnoDB存储引擎中,就规定一条记录的最大长度不能超过数据页大小的1/2。
•InnoDB中数据页的大小由innodb_page_size参数决定,默认为16K。所以,在页长为16K的情况下,InnoDB中一条记录的大小不能超过8K。如果超过了8K,InnoDB会将部分变长字段(VARCHAR)存储在外部页中。
看下面的图思路就清晰些!

如果是向表添加字段的话
要考虑其它字段的大小.因为记录最大字节INNODB 是8192

虽然将BLOB和TEXT存储在外。但即便如此,存储BLOB和TEXT的指针信息也需要9 ~ 12个字节,具体来说:
• TINYTEXT(TINYBLOB): 9 字节
• TEXT(BLOB): 10 字节
• MEDIUMTEXT(MEDIUMBLOB): 11字节
• LONGTEXT(LONGBLOB): 12字节。
作为索引的字段
考虑行格式
1 对于行格式为 REDUNDANT 或 COMPACT 的InnoDB表,索引的最大长度被限制为767字节。
2 将表的行格式设置为 DYNAMIC 或 COMPRESSED,同时开启innodb_large_prefix,索引的最大长度可支持3072字节。
而innodb_large_prefix呢?在 MySQL 5.6 中,默认为OFF。在 MySQL 5.7 中,默认为ON,在 MySQL 8.0中,也移除了。
在 MySQL 5.7 中,innodb_file_format默认为Barracuda,创建表时,如果没有显式指定row_format,则默认为Dynamic。
在 MySQL 8.0 中,innodb_file_format被移除了,取而代之的是innodb_default_row_format。该参数用来设置默认的row_format,默认值为dynamic。
MEMORY引擎的限制
在 MySQL 8.0 .13 之前,内存临时表只支持 MEMORY 引擎,而 MEMORY 引擎会将 VARCHAR 等变长类型作为定长来分配内存。
从 MySQL 8.0.13 开始,内存临时表支持 TempTable 引擎,优化了VARCHAR等变长类型的存储。
使用MYSQL 8.0 没有这些烦恼! 起码少很多! 开发同学爱怎么为所欲为都可以





