在MySQL5.0以上的版本中,varchar数据类型的长度支持到了65535,也就是说可以存放65532个字节的数据,起始位和结束位占去了3个字节,也就是说,在4.1或以下版本中需要使用固定的TEXT或BLOB格式存放的数据可以使用可变长的varchar来存放,这样就能有效的减少数据库文件的大小。
一.VARCHAR存储和行长度限制
1.VARCHAR(N)中,N指的是字符的长度,VARCHAR类型最大支持65535,指的是65535个字节,但并不支持65535长度的varchar,65535中应该包含了所有字段的长度、变长字段长度标示位、NULL标示位的累计。其中内容开头用1到2个字节表示实际长度(长度超过255时需要2个字节)。所以还有别的开销,实际能存放的长度为65532.
(MySQL数据库的varchar类型在5.0.3以下的版本中的最大长度限制为255,其数据范围可以是0~255)
2.因为null标示位占用了一个字节,所以可以去掉not null限制。
3.MySQL要求一个行的定义长度不能超过65535 是指所有列的长度总和不能超过65535.如果列的长度总和超过这个长度,依然无法创建.
二.VARCHAR长度的编码限制
1.概述
字符类型若为gbk,每个字符最多占2个字节,最大长度不能超过32766;
字符类型若为utf8,每个字符最多占3个字节,最大长度不能超过21845。
若定义的时候超过上述限制,则varchar字段会被强行转为text类型,并产生warning。
2.举例
(1)若一个表只有一个varchar类型,如定义为
create table t4(c varchar(N)) charset=gbk;
则此处N的最大值为(65535-1-2)/2= 32766。
减1的原因是实际行存储从第二个字节开始’;
减2的原因是varchar头部的2个字节表示长度;
除2的原因是字符编码是gbk。
(2) 若一个表定义为
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”了。
三.关于SQL模式
在MySQL中,SQL模式常用来解决下面几类问题:
1.通过设置SQL Mode,可以完成不同严格程度的数据校验,有效地保障数据准确性。
2.通过设置SQL Mode为ANSI模式,来保证大多数SQL符合标准的SQL语法,这样应用在不同数据库之间进行迁移时,则不需要对业务SQL进行较大的修改。
3.在不同数据库之间进行数据迁移之前,通过设置SQL Mode可以使MySQL上的数据更方便地迁移到目标数据库中。
查看当SQL模式
mysql>select @@sql_mode;
STRICT_TRANS_TABLES(严格模式) 实现数据的严格校验,使错误数据不能插入表中.
如果将sql_mode设为'',则可能会出现可以建立表,但是会有一条警告信息,
mysql>set session sql_mode='';
mysql>create table test4(a varchar(25000)) charset=utf8;
mysql>show warnings;
警告信息提示了,之所以可以创建,是因为MySQL自动将VARCHAR转换成了Text类型。
mysql>show create table test4;
1、限制规矩
字段的限制在字段定义的时辰有以下规矩:
a) 存储限制
varchar 字段是将实际内容零丁存储在聚簇索引之外,内容开首用1到2个字节默示实际长度(长度跨越255时须要2个字节),是以最大长度不克不及跨越65535。
b) 编码长度限制
字符类型若为gbk,每个字符最多占2个字节,最大长度不克不及跨越32766;
字符类型若为utf8,每个字符最多占3个字节,最大长度不克不及跨越21845。
对于英文斗劲多的论坛 ,应用GBK则每个字符占用2个字节,而应用UTF-8英文却只占一个字节。
若定义的时辰跨越上述限制,则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。
如果某一项中设置的是varchar(50)
那么对英文当然是50
那么对中文呢
utf-8的中文占3个字节
那么,这个varchar(50)是不是只能存16个汉字了?
mysql varchar(50) 不管中文 还是英文 都是存50个的
MySQL5的文档,其中对varchar字段类型这样描述:varchar(m) 变长字符串。M 表示最大列长度。M的范围是0到65,535。(VARCHAR的最大实际长度由最长的行的大小和使用的字符集确定,最大有效长度是65,532字节)。
为何会这般变换?真是感觉MySQL的手册做的太不友好了,因为你要仔细的继续往下读才会发现这段描述:MySQL 5.1遵从标准SQL规范,并且不删除VARCHAR值的尾部空格。VARCHAR保存时用一个字节或两个字节长的前缀+数据。如果VARCHAR列声明的长度大于255,长度前缀是两个字节。
好了,貌似懂了一点。但具体他说的长度大于255时使用2个字节长度前缀,小学减法题:65535 - 2 = 65533啊。不知道这些大牛如何计算的,暂且保留疑问吧?
注:我测试了一下使用UTF8编码,varchar的最大长度为21854字节。
在mysql 5.0.45版本,数据库编码utf8下进行测试:varchar最长定义为21785。也就是说不论字母、数字、汉字,只能放21785个。
推想:varchar字节最大65535,utf8编码一个字符3个字节65535/3=21785。