Mysql中varchar类型一些需要注意的地方
varchar的存储规则
4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节)。
5.0版本以上,varchar(20),指的是20字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放20个,最大大小是65532字节。
varchar字段是将实际内容单独存储在聚簇索引之外,内容开头用1到2个字节表示实际长度。
官方是这么说的:
ValuesinVARCHARcolumnsarevariable-lengthstrings.Thelengthcanbespecifiedasavaluefrom0to255beforeMySQL5.0.3,and0to65,535in5.0.3andlaterversions.
IncontrasttoCHAR,VARCHARvaluesarestoredasaone-byteortwo-bytelengthprefixplusdata.Thelengthprefixindicatesthenumberofbytesinthevalue.
Acolumnusesonelengthbyteifvaluesrequirenomorethan255bytes,twolengthbytesifvaluesmayrequiremorethan255bytes.
varchar和char的区别
区别一,定长和变长
char表示定长,长度固定,varchar表示变长,即长度可变。当所插入的字符串超出它们的长度时,视情况来处理,如果是严格模式,则会拒绝插入并提示错误信息,如果是宽松模式,则会截取然后插入。如果插入的字符串长度小于定义长度时,则会以不同的方式来处理,如char(10),表示存储的是10个字符,无论你插入的是多少,都是10个,如果少于10个,则用空格填满。而varchar(10),小于10个的话,则插入多少个字符就存多少个。
varchar怎么知道所存储字符串的长度呢?实际上,对于varchar字段来说,需要使用一个(如果字符串长度小于255)或两个字节(长度大于255)来存储字符串的长度。但是因为他需要有一个prefix来表示他具体bytes数是多少(因为varchar是变长的,没有这个长度值他不知道如何读取数据)。
区别之二,存储的容量不同
对char来说,最多能存放的字符个数255,和编码无关。
而varchar呢,最多能存放65532个字符。VARCHAR的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是65,532字节
varchar的编码长度限制
字符类型若为gbk,则个字符最多占2个字节,最大长度不能超过32766;字符类型若为utf8,则每个字符最多占3个字节,最大长度不能超过21845。若定义的时候超过上述限制,则varchar字段会被强行转为text类型,并产生warning。
行长度限制
导致实际应用中varchar长度限制的是一个行定义的长度。MySQL要求一个行的定义长度不能超过65535。若定义的表长度超过这个值,则提示ERROR1118(42000):Rowsizetoolarge.Themaximumrowsizefortheusedtabletype,notcountingBLOBs,is65535.YouhavetochangesomecolumnstoTEXTorBLOBs。
这就是说,比如创建一个表,表结构中有两个varhcar类型字段,那么这两个字段的总长度不能超过65535。
官方说明如下:
Everytablehasamaximumrowsizeof65,535bytes.
Thismaximumappliestoallstorageengines,butagivenenginemighthaveadditionalconstraintsthatresultinalowereffectivemaximumrowsize.
varchar的控制位
MySQL中的Varchar字符类型还保留了1个字节来留其它控制信息。
示例
示例一:若一张表中只有一个字段VARCHAR(N)类型,utf8编码,则N最大值为多少?
如:createtabletb_name1(avarchar(N))defaultcharset=utf8,则N最大值=(65535-1-2)/3=21844。
减1的原因是实际行存储从第二个字节开始。
减2的原因是varchar头部的2个字节表示长度。
除3的原因是字符编码是utf8。
sql测试:
createtabletb_name1(avarchar(21844))defaultcharset=utf8; QueryOK,0rowsaffected(0.38sec) droptabletb_name1; QueryOK,0rowsaffected(0.00sec) createtabletb_name1(avarchar(21845))defaultcharset=utf8; ERROR1118(42000):Rowsizetoolarge.Themaximumrowsizefortheusedtabletype,notcountingBLOBs,is65535.Youhavetochangesomecolumns
示例二:若一张表中有一个字段VARCHAR(N)类型,并且有其它的字段类型,utf8编码,则N的最大值为多少?
如:createtabletb_name2(aint,bchar(20),cvarchar(N))defaultcharset=utf8;
则:N最大值=(65535-1-2-4-203)/3=21822
减1的原因是实际行存储从第二个字节开始。
减2的原因是varchar头部的2个字节表示长度。
减4的原因是a字段的int类型占4个字节。
减203的原因是char(20)占用60个字节,编码是utf8。
sql测试:
createtabletb_name2(aint,bchar(20),cvarchar(21822))defaultcharset=utf8; QueryOK,0rowsaffected(0.28sec) droptabletb_name2; QueryOK,0rowsaffected(0.20sec) createtabletb_name2(aint,bchar(20),cvarchar(21823))defaultcharset=utf8; ERROR1118(42000):Rowsizetoolarge.Themaximumrowsizefortheusedtabletype,notcountingBLOBs,is65535.YouhavetochangesomecolumnstoTEXTorBLOBs
示例三:若一张表中有多字段VARCHAR(N)类型,并且有其它的字段类型,gbk编码,则N的最大值为多少?
如:createtabletb_name3(aint,bchar(20),cvarchar(50),dvarchar(N))defaultcharset=gbk;
则:N最大值=(65535-1-1-2-4-202-502)/2=32693
第一个减1的原因是实际行存储从第二个字节开始。
第二个减1表示第二个varchar(50)头部一个1个字节表示长度(小于255)。
减2的原因是varchar头部的2个字节表示长度。
减202的原因是char(20)占用40个字节,编码是gbk。
减502的原因是varchar(50)占用100个字节,编码是gbk。
SQL测试:
createtabletb_name3(aint,bchar(20),cvarchar(50),dvarchar(32694))defaultcharset=gbk; ERROR1118(42000):Rowsizetoolarge.Themaximumrowsizefortheusedtabletype,notcountingBLOBs,is65535.YouhavetochangesomecolumnstoTEXTorBLOBs
createtabletb_name3(aint,bchar(20),cvarchar(50),dvarchar(32693))defaultcharset=gbk; QueryOK,0rowsaffected(0.18sec)
以上就是Mysql中varchar类型一些需要注意的地方的详细内容,更多关于Mysqlvarchar类型的资料请关注毛票票其它相关文章!