一、字符与字节与编码关系
ASCII码中,一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。一个二进制数字序列,在计算机中作为一个数字单元,一般为8位二进制数,换算为十进制。最小值0,最大值255。
UTF-8编码中,一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。
Unicode编码中,一个英文等于两个字节,一个中文(含繁体)等于两个字节。
二、Varchar与char区别
char固定长度的类型:char(M)类型的数据列里,每个值都占用M个字节,如果某个长度小于M,MySQL就会在它的右边用空格字符补足.(在检索操作中那些填补出来的空格字符将被去掉). varchar可变长度的类型:在varchar(M)类型的数据列里,每个值只占用刚好够用的字节再加上一个用来记录其长度的字节(即总长度为L+1字节)
在MySQL中用来判断是否需要进行对数据列类型转换的规则
-
在一个数据表里,如果每一个数据列的长度都是固定的,那么每一个数据行的长度也将是固定的.
-
只要数据表里有一个数据列的长度的可变的,那么各数据行的长度都是可变的.
-
如果某个数据表里的数据行的长度是可变的,那么,为了节约存储空间,MySQL会把这个数据表里的固定长度类型的数据列转换为相应的可变长度类型.例外:长度小于4个字符的char数据列不会被转换varchar类型
在mysql中,char和varchar都表示字符串类型.但他们存储和检索数据的方式并不相同.
在表结构定义中声明char和varchar类型时,必须指定字符串的长度.也就是该列所能存储多少个字符(不是字节,是字符).例如:char(10)和varchar(10)都能存储10个字符.
声明为char的列长度是固定的,char的长度可选范围在0-255之间.也就是char最大能存储255个字符.如果该列是utf8编码,则该列所占用的字节数=字符数3.如果是gbk编码则该列所占用的字节数=字符数2.
声明为varchar的列长度是可变的,mysql5.7.2 varchar的长度范围为0-65535个字节.采用varchar类型存储数据需要1-2个字节(长度超过255时需要2个字节)来存储字符串的实际长度.如果该列的编码为gbk,每个字符最多占用2个字节,最大长度不能超过32766个字符.如果该列的编码为utf8,每个字符最多占3个字节,最大字符长度为21845.
总结:
-
char和varchar最大的不同就是一个是固定长度,一个是可变长度.由于是可变长度,因此存储的是实际字符串再加上一个记录字符串长度的字节。如果分配给char或varchar列的值超过 列的最大长度,则对值进行裁剪.
-
varchar(M)和char(M),M都表示字符数.varchar的最大长度为65535个字节(字符长度为utf8下21845),不同的编码所对应的最大可存储的字符数不同.char最多可以存放255个字符,不同的编码最大可用字节数不同.
三、utf8和gbk编码下的计算方式实例
GBK下: 若一个表只有一个varchar类型,如定义为
create table t4(c varchar(N)) charset=gbk;
则此处N的最大值为(65535-1-2)/2= 32766。
减1的原因是实际行存储从第二个字节开始’;
减2的原因是varchar头部的2个字节表示长度;
除2的原因是字符编码是gbk。
UTF8下:
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。