mysql中varchar最大长度介绍
(2013-12-08 13:04:56)
标签:
varchar字符最大长度 |
分类: Mysql数据库 |
问题描述:
建表报错如下:
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表列类型是有最大长度限制的,限制规则如下:
a)存储限制
varchar
字段是将实际内容单独存储在聚簇索引之外,内容开头会占用1到2个字节存储字符串实际长度(长度超过255时需要2个字节),因此最大长度不能超过65535。
b)编码长度限制
字符类型若为GBK,每个字最多符占2个字节,最大长度不能超过32766;
字符类型若为UTF8,每个字符最多占3个字节,最大长度不能超过21845。
若定义的时候超过上述限制,则varchar字段会被强行转为text类型,并产生warning错误。
c)
行长度限制
导致实际应用中varchar长度限制的还受一个行定义的长度的限制。
MySQL要求一个行的定义长度不能超过65535。若定义的表长度超过这个值,则会报上边提到的那个错误
最后总结下计算某个varchar最大长度的公式:
(65535-1-2-表中其它各字段需要占用的字节数)/该varchar字段字符集的最大字节数=该varchar最大可设置长度
下面以上面公式实际计算下当时实际的建表语句,以出问题的exap_rea字段为计算对象:
CREATE TABLE tts_order_exception (
id int NOT NULL AUTO_INCREMENT,
c2 varchar(64) NOT NULL DEFAULT '',
c3 varchar(64) NOT NULL DEFAULT '',
c4 varchar(64) NOT NULL DEFAULT '',
c5 varchar(64) NOT NULL DEFAULT '',
c6 varchar(256) NOT NULL DEFAULT '',
c7 varchar(256) NOT NULL DEFAULT '',
c8 varchar(256) NOT NULL DEFAULT '',
exap_rea varchar(25600) NOT NULL DEFAULT '',
createTime datetime DEFAULT NULL,
verify_times int DEFAULT 0,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
(65535-1-2-4-64*4*3-1*4-256*3*3-2*3-8-4)/3
= 20811
经过计算得出exap_rea最大可设长度为20811
以上表达式解释说明如下:
减1的原因:实际行存储从第二个字节开始。
减2的原因:(exap_rea) varchar头部的2个字节表示长度长度。
减4的原因:int类型的id字段占4个字节。
减64*4*3的原因:4个长度64 UFT8 varchar类型的c2, c3, c4, c5字段占64*4*3个字节。
减1*4的原因:4个长度64 varchar类型头部需要1*4个字节保存字符串长度信息。
减256*3*3的原因:3个长度256 UFT8 varchar类型的c6, c7, c8字段占256*3*3个字节。
减2*3的原因:3个长度256 varchar类型头部需要2*3个字节保存字符串长度信息。
减8的原因:datetime类型的createTime字段占8个字节长度。
减4的原因是int类型的verify_times字段占4个字节长度。
最后除3的原因是字符编码是UTF8。
最后验证下计算是否正确:
修改为exap_rea varchar(20811) NOT NULL
DEFAULT '',
建表成功。
修改为exap_rea varchar(20812) NOT NULL
DEFAULT '',
建表时报Row size too large错。
测试发现:
建表时,一个text字段占用10个字节,一个blob字段占用10个字节;
Mysql5.0以下版本,varchar(10)中,10表示10个字节;5.0版本以上,varchar(10)中,10表示10个字符,如果是utf8,则占用10*3=30个字节,utf8mb4的话,是40字节;gbk的话,是20字节

加载中…