【转】MySQL中varchar最大长度是多少?
一. varchar存储规则:
4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节)
5.0版本以上,varchar(20),指的是20字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放20个,最大大小是65532字节
Mysql4中最大也不过是20个字节,但是Mysql5根据编码不同,存储大小也不同。
二. varchar和char 的区别:
char是一种固定长度的类型,varchar则是一种可变长度的类型,它们的区别是: char(M)类型的数据列里,每个值都占用M个字节,如果某个长度小于M,MySQL就会在它的右边用空格字符补足.(在检索操作中那些填补出来的空格字符将被去掉)在varchar(M)类型的数据列里,每个值只占用刚好够用的字节再加上一个用来记录其长度的字节(即总长度为L+1字节).
在MySQL中用来判断是否需要进行对据列类型转换的规则
1、在一个数据表里,如果每一个数据列的长度都是固定的,那么每一个数据行的长度也将是固定的.
2、只要数据表里有一个数据列的长度的可变的,那么各数据行的长度都是可变的.
3、如果某个数据表里的数据行的长度是可变的,那么,为了节约存储空间,MySQL会把这个数据表里的固定长度类型的数据列转换为相应的可变长度类型.例外:长度小于4个字符的char数据列不会被转换为varchar类型
被问到一个问题:MySQL中varchar最大长度是多少?这不是一个固定的数字。本文简要说明一下限制规则。
1、限制规则
字段的限制在字段定义的时候有以下规则:
a) 存储限制
varchar 字段是将实际内容单独存储在聚簇索引之外,内容开头用1到2个字节表示实际长度(长度超过255时需要2个字节),因此最大长度不能超过65535。
b) 编码长度限制
字符类型若为gbk,每个字符最多占2个字节,最大长度不能超过32766;
字符类型若为utf8,每个字符最多占3个字节,最大长度不能超过21845。
若定义的时候超过上述限制,则varchar字段会被强行转为text类型,并产生warning。
c) 行长度限制
导致实际应用中varchar长度限制的是一个行定义的长度。 MySQL要求一个行的定义长度不能超过65535。若定义的表长度超过这个值,则提示
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。
2、计算例子
举两个例说明一下实际长度的计算。
a) 若一个表只有一个varchar类型,如定义为
create table t4(c varchar(N)) charset=gbk;
则此处N的最大值为(65535-1-2)/2= 32766。
减1的原因是实际行存储从第二个字节开始’;
减2的原因是varchar头部的2个字节表示长度;
除2的原因是字符编码是gbk。
b) 若一个表定义为
create table t4(c int, c2 char(30), c3 varchar(N)) charset=utf8;
则此处N的最大值为 (65535-1-2-4-30*3)/3=21812
减1和减2与上例相同;
减4的原因是int类型的c占4个字节;
减30*3的原因是char(30)占用90个字节,编码是utf8。
如果被varchar超过上述的b规则,被强转成text类型,则每个字段占用定义长度为11字节,当然这已经不是“varchar”了。
则此处N的最大值为 (65535-1-2-4-30*3)/3=21812
create table t4(c int, c2 char(30), c3 varchar(21812)) ENGINE=InnoDB DEFAULT CHARSET=utf8
create table t5(c int, c2 varchar(30), c3 varchar(21812)) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `t` (
`var` varchar(21844) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
可以正常的执行。
[SQL] CREATE TABLE `t` (
`var` varchar(21845) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
[Err] 1118 - 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]如何计算varchar最大长度
表设计如下
| id | mediumint |
| name | varchar |
问题是: MySQL5.1 , 在GBK字符环境下,这里的varchar最长能设多长?
正确答案是: 32764
那如果表设计为两个 varchar, 第一个长度设为300时,第二个varchar应该多长? --答案见本文最后面
要想搞明白是怎么算出来的,请仔细下面的解释:
官方文档上对 int 及 varchar 的说明如下:

Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 255 before MySQL 5.0.3, and 0 to 65,535 in 5.0.3 and later versions.
看到这里,你以为上面的varchar长度是: 65535 /2=32767?
不对,因为官方文档后面又说:
In contrast to CHAR, VARCHAR values are stored as a one-byte or two-byte length prefix plus data. The length prefix indicates the number of bytes in the value.
很明白了,varchar会保留一至两个字节来存放长度信息,但到底是1Byte还是2Byte?
往后看:
A column uses one length byte if values require no more than 255 bytes, two length bytes if values may require
more than 255 bytes.
你再来算一算varchar长度 最大为: (65535-2) /2 = 32766 ?
还是不对!
其实每一行的总长度是有限制的,即最大为65535.
Every table has a maximum row size of 65,535 bytes.
This maximum applies to all storage engines, but a given engine might have additional constraints that result in a lower effective maximum row size.
所以算varchar得把id的扣除:
(65535-3-2) /2 = 32765 ?
测试一下:
root@saker 05:27:28>create table t4(id mediumint, name varchar(32765));
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
用32764测试一下:
root@saker 05:27:31>create table t4(id mediumint, name varchar(32764));
Query OK, 0 rows affected (0.16 sec)
root@saker 05:27:35>desc t4;
+-------+----------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| id | mediumint(9) | YES | | NULL | |
| name | varchar(32764) | YES | | NULL | |
+-------+----------------+------+-----+---------+-------+
这说明还保留了1至2个字节来留其它控制信息。(在文档里面我没有找到说明,所以也不知道到底是1个还是2个byte)
但我想到了一个方法来反推出来,
我把id的类型从medium改成 int ,这时id的长度就从3变为4了,如果控制字节用了2Bytes,那varchar的长度还设为32764的话,显然是要报错的。。。
root@saker 05:29:14>create table t3(id int, name varchar(32764));
Query OK, 0 rows affected (0.18 sec)
root@saker 07:01:10>desc t3;
+-------+----------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(32764) | YES | | NULL | |
+-------+----------------+------+-----+---------+-------+
这样应该能说明,控制位只有1个字节。
下面用这个结论来计算第二个问题:
那如果表设计为两个 varchar, 第一个长度设为300时,第二个varchar应该多长?
(65535-1-2-2-300*2) /2 = 32465
测试一下:
root@saker 07:09:23>create table t1(id varchar(300), name varchar(32465));
Query OK, 0 rows affected (0.15 sec)
root@saker 07:09:26>desc t1;
+-------+----------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| id | varchar(300) | YES | | NULL | |
| name | varchar(32465) | YES | | NULL | |
+-------+----------------+------+-----+---------+-------+
2 rows in set (0.02 sec)
多一位都不行:
root@saker 07:08:12>create table t1(id varchar(300), name varchar(32466));
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
最后 把以上所有知识综合起来:
有一个表:
id int, name1 char(20), name2 varchar(100), name3 varchar(?)
算一下:
(65535-1-1-2-4-20*2-100*2) /2 = 32643
root@saker 07:16:09>create table tt(id int, name1 char(20), name2 varchar(100), name3 varchar(32643));
Query OK, 0 rows affected (0.18 sec)
root@saker 07:16:12>desc tt;
+-------+----------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name1 | char(20) | YES | | NULL | |
| name2 | varchar(100) | YES | | NULL | |
| name3 | varchar(32643) | YES | | NULL | |
+-------+----------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
root@saker 07:15:08>create table tt(id int, name1 char(20), name2 varchar(100), name3 varchar(32644));
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中varchar最大长度是多少?的更多相关文章
- int(11)最大长度是多少,MySQL中varchar最大长度是多少(转)
int(11)最大长度是多少,MySQL中varchar最大长度是多少? int(11)最大长度是多少? 在SQL语句中int代表你要创建字段的类型,int代表整型,11代表字段的长度. 这个11代表 ...
- MySQL中varchar最大长度是多少?
一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...
- MySQL中varchar最大长度是多少
一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...
- 浅谈mysql中varchar(m)与char(n)的区别与联系
mysql建表长度的限制 在mysql建表时,出现以下报错信息: 错误一:行大小过大,所使用的表这种类型的最大的行大小,不算BLOB类型,是65535.(这是我翻译的) 原因是MySQL在建表的 ...
- MySQL中varchar与char区别
MySQL中varchar与char区别(转) MySQL中varchar最大长度是多少? 一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字 ...
- Mysql中varchar和char区别
一.varchar和char的区别: 区别一:定长和变长 char表示定长.长度固定,varchanr表示变长,即长度可变. 即char类型是规定多少字长则必须存储多少字长,超过的长度的字段则只能截取 ...
- MySql中varchar和char,如何选择合适的数据类型?
背景 学过MySQL的同学都知道MySQL中varchar和char是两种最主要的字符串类型,varchar是变长的类型,而char是固定长度.那关于如何选择类型就成为令人头疼的事,很多初学者为了保证 ...
- MySQL的varchar定义长度到底是字节还是字符
相信这个问题也会困扰不少人,尤其是使用过其它数据库(如Oracle)的人,之前我也没有太在意这个问题,再加上一些书籍和网上的文章讲的不够细致,又没测试过,导致我一直理解错误.下面通过实例来解释,在开始 ...
- mysql中的数据类型长度
“mysql中的数据类型长度是固定的 数据类型后面改的只是展示长度 没用的 int就是四个字节 2的31次方减一是最大值 所以改这个长度没用 只能改数据类型”
随机推荐
- html select的事件 方法 属性
事件 onactivate 当对象设置为活动元素时触发. onafterupdate 当成功更新数据源对象中的关联对象后在数据绑定对象上触发. onbeforeactivate 对象要被设置为当前元素 ...
- 如何在WPF的DiagramControl中绘制一个类型数据关系图的方法
https://www.devexpress.com/Support/Center/Question/Details/T418156 虽然是在wpf中,但是在win中也可以调用wpf控件,这个太棒了, ...
- mySQL数据库Sql语句执行效率检查--Explain命令
mysql性能的检查和调优方法 Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 果,可以帮助选择更好的 ...
- 虚拟现实外包公司—焰火工坊CTO团队外包难把VR真正做起来,讲故事可能将伤害产业链
CTO王明杨,带着他的焰火工坊,正在为自家VR播放器和系统的上线做最后准备.不少投资机构,有传言称包括小米在内巨头都试图染指VR领域,而上月上市的暴风影音正是倚靠VR的概念成功助推了其高股价.对此,王 ...
- 个人博客作业Week3
一.调研 下载并使用,按照描述的bug定义,找出几个功能性的比较严重的bug.至少两个.用专业的语言描述(每个bug 不少于 40字),如有必要,可以配图. 电脑用户未登录就能使用单词本功能,万一是用 ...
- yyyy-MM-dd与YYYY-MM-dd
Date date=new Date(); DateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:MM:SS"); DateForm ...
- iOS - Bitcode App 瘦身中间码
1.Bitcode 随着 Xcode7 的发布,Apple 提供了一项新的技术来支持 App 瘦身功能,那就是 Bitcode. 1.BitCode 是什么 Bitcode is an interme ...
- HTML5扩展之微数据与丰富网页摘要
一.微数据是? 一个页面的内容,例如人物.事件或评论不仅要给用户看,还要让机器可识别.而目前机器智能程度有限,要让其知会特定内容含义,我们需要使用规定的标签.属性名以及特定用法等.举个简单例子,我们使 ...
- asp.net 一句话搞定分页
rows 是客户端传过来的行数,page是页码,传参就需要就两个参数就行,sql语句中_row 和_page 自己声明的局部变量,值还是相应的row 和page ,为了运算而已. 用数据库类获得它的D ...
- lua特性纪要
[局部变量] lua的局部变量通过local进行显示声明, 其作用域仅限于声明它的块block.这里的block分为三种类型: 1.控制结构的执行体 2.函数的执行体 3.chunk 比较容易引起混淆 ...