各个数据库对varchar类型的长度定义是不大一样的,拿DM举例,varchar类型长度上限和数据库页大小和表的定义有关,而且最大上限不超过8188字节。具体不同页大小设置对varchar大小上限的影响可以看我的上一篇博客 。
这篇文章,我主要测试的是另外两个参数,UNICODE_FLAG(或CHARSET)与LENGTH_IN_CHAR对varchar的影响。
UNICODE_FLAG/CHARSET:数据库字符集,包含了数据字典的字符集,该参数和page_size一样一经初始化便无法修改。我们最常用的字符集是UTF-8和GB18030。1代表UTF-8,0代表GB18030。
LENGTH_IN_CHAR:varchar类型对象是否以字符为单位(默认为0),1表示以字符为单位,0表示以字节为单位。需要注意的是varchar以字符为单位时,数据库将存储长度按照理论字符长度进行放大,varchar的最大字节数仍然为8188,例如:编码为UTF-8时,一个字符占用4个字节,那么varchar(1)就占用了一个字符即4个字节。
一、情况一,UNICODE_FLAG=0,LENGTH_IN_CHAR=0
此时字符集为GB18030,varchar以字节为单位。
1、创建测表t1并插入数据test初始化为varchar(1):
create table t1 (test varchar(1));
insert into t1 values('1');
insert into t1 values('a');
insert into t1 values('中');
可以看到,varchar(1)能正常插入数字与英文字母,不能插入汉字。
2、查询t1表中数据的字符个数length与所占字节数lengthb:
select test, length(test), lengthb(test) from t1;
可以看到varchar(1)对应一个字节,一个数字或字母占用一个字节。
3、创建表t2,并插入数据(test初始化为varchar(3)):
create table t2 (test varchar(3));
insert into t2 values('中');
insert into t2 values('中国');
4、 查询t2表中数据的字符个数length与所占字节数lengthb:
可以看出,UNICODE_FLAG=0,LENGTH_IN_CHAR=0, 此时字符集为GB18030,varchar以字节为单位。一个英文对应一个字节,一个汉字对应两个字节。
二、情况二,UNICODE_FLAG=0,LENGTH_IN_CHAR=1
此时字符集为GB18030,varchar以字符为单位。(注意这是一个新的数据库实例,因为这两个参数时不允许修改的,所以要测试不同的参数必须新初始化一个实例)
1、创建测表t1并插入数据test初始化为varchar(1):
create table t1 (test varchar(1));
insert into t1 values('1');
insert into t1 values('ab');
insert into t1 values('abc');
insert into t1 values('中');
insert into t1 values('中国');
varchar(1)最多容纳两个字母或者一个汉字。
2、查询t1表中数据的字符个数length与所占字节数lengthb:
select test, length(test), lengthb(test) from t1;
可以看出,UNICODE_FLAG=0,LENGTH_IN_CHAR=1,字符集为GB18030,varchar以字符为单位时,一个字符对应两个字节,一个数字、字母占用一个字节,一个汉字占用两个字节。
三、情况三,UNICODE_FLAG=1,LENGTH_IN_CHAR=0
此时字符集为UTF-8,varchar以字节为单位。
1、创建测表t1并插入数据test初始化为varchar(1):
create table t1 (test varchar(1));
insert into t1 values('1');
insert into t1 values('ab');
insert into t1 values('中');
varchar(1)最多可以容纳一个数字或字母,无法插入汉字。
2、创建测表t2并插入数据test初始化为varchar(3):
create table t2 (test varchar(3));
insert into t2 values('abc');
insert into t2 values('中');
insert into t2 values('中国');
varchar(3)可以容纳三个字母,汉字最多插入一个。
3、 查询t2表中数据的字符个数length与所占字节数lengthb:
select test, length(test), lengthb(test) from t2;
总结,UNICODE_FLAG=1,LENGTH_IN_CHAR=0,字符集为UTF-8,varchar以字节为单位。此时,一个数字、字母占用一个字节,一个汉字占用三个字节。
四、情况四,UNICODE_FLAG=1,LENGTH_IN_CHAR=1
此时字符集为UTF-8,varchar以字符为单位。
1、创建测表t1并插入数据test初始化为varchar(1):
create table t1 (test varchar(1));
insert into t1 values('1');
insert into t1 values('a');
insert into t1 values('abcd');
insert into t1 values('abcde');
insert into t1 values('中');
insert into t1 values('中国');
varchar(1)中字母最多可以插入四个,汉字可以插入一个。
2、 查询t1表中数据的字符个数length与所占字节数lengthb:
select test, length(test), lengthb(test) from t1;
可以看到,一个字母占用一个字节,一个汉字占用3个字节。
3、创建测表t2并插入数据test初始化为varchar(3)
create table t2 (test varchar(3));
insert into t2 values('123456789012');
insert into t2 values('1234567890123');
insert into t2 values('中国富强');
insert into t2 values('实现中国梦');
varchar(3)最多可以插入12个英文,4个汉字。
4、查询t2表中数据的字符个数length与所占字节数lengthb:
select test, length(test), lengthb(test) from t2;
总结,在UNICODE_FLAG=1,LENGTH_IN_CHAR=1的情况下,字符集为UTF-8,varchar以字符为单位。此时一个数字、字母、汉字均占用一个字符。一个数字、字母占用一个字节,一个汉字占用三个字节,一个字符对应四个字节,varchar长度为3时,最多可以录入4个汉字(4*3=12个字节),12个字母。
五、总结
varchar(1) | 字符集GB18030 以字符为单位 | 字符集GB18030 以字节为单位 | 字符集UTF-8, 以字符为单位 | 字符集UTF-8, 以字节为单位 |
占用字节数 | 2 | 1 | 4 | 1 |
汉字占用字节数 | 2 | 2 | 3 | 3 |
英文占用字节数 | 1 | 1 | 1 | 1 |
存储汉字 | 1 | 0 | 1 | 0 |
存储英文 | 2 | 1 | 4 | 1 |
如果还有任何问题,欢迎到达梦云适配中心提问哦!