前言
注:本文的实践是在oracle数据库中进行的,主要基于字节与字符以及定长与变长方面考虑,探索这四个类型的部分区别
Oracle数据库中,char、varchar、varchar2、nvarchar2是我们常用到的数据类型
(MySQL中没有varchar2和nvarchar2,也可以参考本文来比较MySQL中char和varchar的区别)
下面我们做一个简单的实验吧:
首先创建一个表,里面有aa,bb,cc,dd四个字段,类型分别是char、varchar、varchar2、nvarchar2。如下图所示:
一、变长与定长
我们用下面的SQL语句插入一条数据,所有的字段都是5个字节代表的数字,排除了字符和字节的影响:
[sql]view plaincopy
- insertinto test (aa, bb, cc, dd)
- values
- ('01234', '01234', '01234', '01234');
我们看下下图中的蓝底背景:
aa字段(蓝色部分较长,因为右边有5个空格):
bb字段
cc字段
dd字段
对比上面的4张图中的蓝色部分长度,aa字段的值最长,其他都相同。
我们可以得出下面的结论:
char是固定长度,长度不够的情况下,用空格代替
varchar、varchar2、nvarchar2是可变长度,按照实际的长度存储
二、存储单位
1、默认存储单位
用下面的SQL语句插入一条数据,所有的字段都是10个汉字(因为汉字是字符类型,排除变长与定长的影响)
[sql]view plaincopy
- insertinto test (aa, bb, cc, dd)
- values
- ('一二三四五六七八九十', '一二三四五六七八九十', '一二三四五六七八九十', '一二三四五六七八九十');
出现如下错误,提示最大值是10:
把aa改为一二三四五,其他字段不变,又报错,提示最大值是10:
把bb改为一二三四五,cc、dd字段不变,又出现错误,提示最大值是10
把cc改为一二三四五试一下,插入成功!查询一下:
再用下面的SQL语句插入一条数据,所有的字段都是数字(因为数字是字节类型)
[sql] view plain copy
1.insert into test (aa, bb, cc, dd)
2.values
3.('0123456789', '0123456789', '0123456789', '0123456789');
直接插入了,没有报错!得到下面的结果:
上面的操作可以得出:char、varchar、varchar2默认存储单位是字节,nvarchar2默认存储单位是字符
2、其它存储单位
2.1 char、varchar、varchar2还可以用字符作为单位
既然char、varchar、varchar2默认存储单位是字节,那么这三种类型能不能用字符作为存储单位呢?
用下面的例子来测试,结果是都可以插入:
2.2 nvarchar2不能用字节作为存储单位
char、varchar、varchar2的长度单位可以是byte和char,那么nvarchar2的长度单位能不能是byte呢?
请看下面这个实验:把四个字段都设置成byte类型,则发生报错:
而把前三个设置为byte,最后一个默认呢?下面的实验表示可以成功创建表以及插入数据:
通过上面的操作,我们可以得出以下结果:
char、varchar、varchar2存储长度单位可以是字节,也可以是字符。
nvarchar2存储长度单位是字符!
3 探索过程中的一个问题
创建表时,nvarchar2 类型里不能有长度单位char,否则会报错:
结论
1、长度的区别:
char是固定长度,长度不够的情况下,用空格代替
varchar、varchar2、nvarchar2是可变长度,按照实际的长度存储
2、存储单位的区别:
char(byte), char(char),其中字节是默认单位
varchar(byte), varchar(char),其中字节是默认单位
varchar2(byte), varchar2(char),其中字节是默认单位
nvarchar2() 默认存储单位是char,且括号里不能有单位
3、其他区别
关于其他的区别,有最大存储、存储效率等,这里不做实验,推荐两篇文章作为参考