EasyText, EasyLicense 的作者, https://github.com/EasyHelper Good Good Study,Day Day Up.

 

谈谈char ,nchar,varchar,nvarchar 和Uniqueidentifier

SQL server数据库中这几个类型应该是比较常用的,这篇文章主要也是和大家一起讨论下这几个类型。

先重点看前面4个:char ,nchar,varchar,nvarchar

Msdn解释如下:

固定长度或可变长度的字符数据类型。

char [ ( n ) ]

固定长度,非 Unicode 字符数据,长度为 n 个字节。n 的取值范围为 1 8,000,存储大小是 n 个字节。char ISO 同义词为 character

varchar [ ( n | max ) ]

可变长度,非 Unicode 字符数据。n 的取值范围为 1 8,000max 指示最大存储大小是 2^31-1 个字节。存储大小是输入数据的实际长度加 2 个字节。所输入数据的长度可以为 0 个字符。varchar ISO 同义词为 char varying character varying

字符数据类型(nchar 长度固定,nvarchar 长度可变)和 Unicode 数据使用 UNICODE UCS-2 字符集。

nchar [ ( n ) ]

n 个字符的固定长度的 Unicode 字符数据。n 值必须在 1 4,000 之间(含)。存储大小为两倍 n 字节。nchar ISO 同义词为 national char national character

nvarchar [ ( n | max ) ]

可变长度 Unicode 字符数据。n 值在 1 4,000 之间(含)。max 指示最大存储大小为 2^31-1 字节。存储大小是所输入字符个数的两倍 + 2 个字节。所输入数据的长度可以为 0 个字符。nvarchar ISO 同义词为 national char varying national character varying  

var->vary(变化),所以带有var 的类型都是可变长度的。

n->national(国际化),因为UTF8不足够表示中文,韩文,日文,所以为了支持国际化,有了Unicode的编码,所以以n开头的字段代表着这个类型是unicode编码。

 

实例演示:

创建表:

CREATE TABLE [dbo].[TestTable](

    [char_Col] [char](5) NULL,

    [nchar_Col] [nchar](5) NULL,

    [nvarchar_Col] [nvarchar](5) NULL,

    [varchar_Col] [varchar](5) NULL,

) ON [PRIMARY]

上面的n都是5,代表长度是5.

接着插入一行数据:

insert into TestTable select '1','1','1','1'

如果查看表可以看到:

image

仔细的数一数可以发现后面是4个空格,nchar_Col也是4个空格。这点说明对于定长类型char,nchar如果长度不足的话,在后面补充空格。

image

因为带有var,所以长度变了,后面不会有空格。

结论:使用长度固定的类型的时候,可能要做Trim操作,当然也可以选择RTrim,因为是在后面补充空格的。

2:执行下面的Sql语句:

insert into TestTable(char_Col,nchar_Col,nvarchar_Col,varchar_Col)

            values('王王王王王','王王王王王','王王王王王','王王王王王')

结果如下:

image

charvarchar的长度是5,但是它们存储的是非Unicode字符,采用一个字节的形式来存储数据。

Nchar nvarchar 的长度也是5,但是存储的是Unicode字符,采用两个字节来存储数据,也就是是说对于任何字符,都采用两个字节来存储,不管是数字还是字母,或者是英文,总之任何字符都采用两个字节来储存。

在上面的例子中,是中文,所有的中文都用两个字节表示,

所以上面的Sql语句就代表 select 10个字节,10个字节,10个字节,10个字节。

我们的表定义设置了所以的n5,这里n是类型(n) 中的n

char(5):存储5个字节,对于10个字节来说需要截断。

nchar(5):存储的是5*2个字节,对于10个字节来说,合适

varchar(5) :存储5个字节,对于10个字节来说需要截断。

nvarchar(5):存储的是5*2个字节,对于10个字节来说,合适

 

为了验证:执行下面的sql语句

insert into TestTable(char_Col,nchar_Col,nvarchar_Col,varchar_Col)

             values('王王a','12345','王王王王王','12345')

结果:

image

一个中文2个字符,所以王王a’ 一共5个字符。

修改代码为:

insert into TestTable(char_Col,nchar_Col,nvarchar_Col,varchar_Col)

             values('王王a','123456','王王王王王','12345')

和上面的不同是将nchar_Col加了个6.

结果:

image

 

为什么?

nchar是存储Unicode字符的,所以不管任何字符,都采用两个字节来存储。”123456” 的长度是6,所以需要的字节是6*2=12个字节,对于nchar(5) 只能存储10个字节来说”123456” 会被截断。

这里就是要注意对于nchar,nvarchar 来说,这两个数据类型是用来存储Unicode的,所以任何字符都采用两个字节来存储,也就是nchar(n),nvarchar(n) 中的n代表的就是字符串的长度。

N=5,所以可以存储”12345”,’王王王王5”,” 王王王王王”,” ade1”,这些字符串的长度都是5

但是对于char(n),varchar(n) 来说,n代表的是字节。

例如

N=5,所以可以存储”12345”,”王王a”,”abd”.一个汉字两个字节,这些字符串的字节全部都是5

 

关于何时使用char,varchar,nchar,nvarcharmsdn给了一部分建议

·         如果列数据项的大小一致,则使用 char

·         如果列数据项的大小差异相当大,则使用 varchar

·         如果列数据项大小相差很大,而且大小可能超过 8,000 字节,请使用 varchar(max)

·         如果需要支持Unicode,使用nchar,nvarchar

 

在早期的Sql Server 版本中,如果要存储大量的字符串,可以采用ntext,text,image 数据类型,不过微软建议:

image

 

Uniqueidentifier16字节GUID

如果应用程序要使用guid来作为表的id的话,你会选择什么数据类型?

char(36) ,nchar(36), varchar(36), nvarchar(36) 还是uniqueidentifier

假设guid为xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,长度是36.

很明显,你不会选择nchar(36),nvarchar(36).因为guid不会有中文,而且nchar(36),nvarchar(36)代表着72个字节。

其次你应该不会选择varchar(36),因为一个guid不做处理的话,长度是固定的。

剩下来就是char(36) 和uniqueidentifier之争了

Uniqueidentifier需要16字节GUID,char(36) 需要36个字节,你会选择什么数据类型?

为什么Uniqueidentifier 16个字节就可以存储guid?

msdn 解释:

通过从 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 形式的字符串常量进行转换,其中,每个 x 都是 0-9 a-f 范围内的十六进制数字。例如,6F9619FF-8B86-D011-B42D-00C04FC964FF 为有效的 uniqueidentifier 值。

 

posted @ 2012-02-06 21:16  LoveJenny  阅读(5329)  评论(7编辑  收藏  举报
EasyText, EasyLicense 的作者, https://github.com/EasyHelper Good Good Study,Day Day Up.