sql中的字符类型char,varchar,nchar,nvarchar
在sql中我们常常会用到如char,varchar,nchar,nvarchar这几种常见的字符类型。其中按照是否为可变长度类型分为带var的可变类型varchar与nvarchar以及不带var的固定长度类型char和nchar;按照是否存储unicode编码类型分带n的nchar和nvarchar两种unicode类型以及不带n开头的char和varchar非unicode类型。下面分别解释下。
1、是否可变长度
通常我们定义类型类似这样char(n),varchar(n),nchar(n),nvarchar(n)其中非char,varchar中的n表示字节数最大为8000,而nchar,nvarchar中的n表示最大字符数为4000,对于这几类自定义长度的类型来说,每种类型最大允许存储8000个字节(定义为max的除外),注意这边的字节与前面说的字符不一样 。所谓的固定长度值即使所占的字符大小为达到预定的字节大小,但是存储所占的大小还是会按照原先的定义。如下例子
declare @str1 char(10);
declare @str2 varchar(10);
set @str1='abc123';
set @str2='abc123';
select datalength(@str1),datalength(@str2);
select len(@str1),len(@str2);
--datalength用来计算实际所占的字节数,len用来计算存储的字符数
----------- -----------
10 6
(1 行受影响)
----------- -----------
6 6
(1 行受影响)
虽然上面的 变量@str1只存储了6个字符,且都是单字节的,但其实际还是占用了10个字节的空间,
而可变类型的变量@str2却是按照实际的存数字符来计算,跟原先的定义的初始大小无关,只会在超出大小的时候进行截断炒作。 nchar与nvarchar同理。
2,unicode类型与非unicode类型
对于一般的非unicode编码字符来说像字母、数字等1个字符为一个字节长度,而中文中的汉字则占两个字节,所以存储同样字符数的数据,有可能就占了不同的数据长度,看例子
declare @str1 varchar(10);
declare @str2 varchar(10);
set @str1='abc123';
set @str2='abc中文的';
select datalength(@str1),datalength(@str2);
select len(@str1),len(@str2);
--datalength用来计算实际所占的字节数,len用来计算存储的字符数
结果显示
----------- -----------
6 9
(1 行受影响)
----------- -----------
6 6
(1 行受影响)
上面我们看到,虽然我们为两个变量都存储了6个字符数据,但结果所占的字节数是不一样的,明显中文的每个字符占用的是两个字节,所以其实所谓的最大存8000个字节针对非中文的字母数字以及那些只占一个字节的字符就可以存8000个字符,如果全是中文字符,那只能存储4000个字符。也就是4000个字符之内你不用担心的,如果超过4000个字符你就要考虑到是否全是中文的,如果是中文的肯定超出储存的最大限度了,超出部分就会被截断。
而unicode类型的字符其实不管是不是中文,还是英文数字,乃至任何字符都是按照2个字节来存储的,所以其实如果我们定义unicode类型的数据就必须将nvarchar(n),nchar(n)中的n限定在4000个字符内,否则实际存储就会超过8000个字节。看下面例子,不管有没有带中文的都占了12个字节数。
declare @str1 nvarchar(10);
declare @str2 nvarchar(10);
set @str1='abc123';
set @str2='abc中文的';
select datalength(@str1),datalength(@str2);
select len(@str1),len(@str2);
--datalength用来计算实际所占的字节数,len用来计算存储的字符数
----------- -----------
12 12
(1 行受影响)
----------- -----------
6 6
(1 行受影响)
如果我们定义下面则报错
消息 2717,级别 16,状态 2,第 2 行
为 参数'@str1' 指定的大小(4001)超过了最大允许值(4000)。
好了该说的说完了,当然除了以上的那些定义外 sql中还有类似text,ntext等字符类型,不过在sql2005级以后通常建议用varchar(max),nvarchar(max)来代替。