SQL Server中的nchar,nvarchar,text,ntext,char,varchar比较
参考文献:
http://www.cnblogs.com/mekong/archive/2009/04/17/1437996.html
http://msdn.microsoft.com/en-us/library/ms186939.aspx
前言
这几天在查阅sql server collation的问题,这其中就牵涉到了unicode,non-unicode,varchar,nvarchar,ANSI等字符编码的问题。首先我们讲解一些基础背景知识
定长或变长
所谓定长就是长度固定的,当输入的数据长度没有达到指定的长度时将自动以英文空格在其后面填充,使长度达到相应的长度;有var前缀的,表示是实际存储空间是变长的,比如varchar,nvarchar变长字符数据则不会以空格填充,比较例外的是,text存储的也是可变长。
Unicode或non-Unicode
数据库中,英文字符只需要一个字节存储就足够了,但汉字和其他众多非英文字符,则需要两个字节存储。如果英文与汉字同时存在,由于占用空间数不同,容易造成混乱,导致读取出来的字符串是乱码。Unicode字符集就是为了解决字符集这种不兼容的问题而产生的,它所有的字符都用两个字节表示,即英文字符也是用两个字节表示。而前缀n就表示Unicode字符,比如nchar,nvarchar,这两种类型使用了Unicode字符集。
至于为什么英文字幕是一个字符,占用一个字节,而汉字是两个字符,占用两个字节。这是因为英文字幕只有26个,一个字节有8位,对应着有2^8=256种编码对应,远大于26,因此可以用一个字节来存储。但是汉字的数量远远大于一个字节所能对应的编码数量,所以必须使用两个字节,也就有了2^16=65536种编码对应每一个汉字。在unicode字符集中,汉字占了5万多个。
字段容量
接下来我们看一下char,varchar,nchar和nvarchar能存储多个内容,如下表所示:
char,varchar | 最多8000个英文,4000个汉字 |
nchar,nvarchar | 可存储4000个字符,无论英文还是汉字 |
分析1:
之索引是8000,是因为在sqlserver中一个page是8kb,而用于存储行数据的只有8060字节。这四种数据类型用于修饰表中的一个列,所以列的长度肯定不能大于8060,剩下的60字节具体做什么还不清楚。
分析2:
varchar是按字节存储的,而nvarchar是按字符存储的 。比如说 , varchar(40),能存储40个字节长度的字符,存储中文字符的时候,因为中文字符1个字符就等于2个字节。所以varchar(40)只能存储20个中文字符。nvarchar(40),就可以存储40个中文字符,但是它所占用的存储空间是80字节,但是还是只能存储40个英文字符。
实验说明:
--实验1:测试nvarchar和varchar的存储长度 --创建一个默认collation为Chinese_PRC_CI_AS的数据库TESTDB3 USE TESTDB1 CREATE TABLE test ( lastname NVARCHAR(8) NOT NULL,--nvarchar类型,双字节存储 title VARCHAR(8) NOT NULL, --varchar类型,单字节存储 ); insert into test values('姓名1','标题1'); select * from test; insert into test values('123456789','1');--String or binary data would be truncated. insert into test values('12345678','1'); insert into test values('1','12345678'); insert into test values('一二三四五六七八','一二三四'); select * from test; --总结: /* 1.nvarchar(n),按字符来存储,不论是英文字符还是中文字符。最多能够存储n个中文或者是英文,但是所占用的存储空间是2n+2个字节。1<=n<=4000 2.varchar(n)按字节存储,最多能够存储n个英文字母,存储n/2个中文字符。但是所占用的存储空间是n个字节。1<=n<=8000 */
CHAR 和 VARCHAR
CHAR
- 存储定长数据很方便,CHAR字段上的索引效率级高,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间。
VARCHAR
- 存储变长数据,但存储效率没有CHAR高,如果一个字段可能的值是不固定长度的,我们只知道它不可能超过10个字符,把它定义为 VARCHAR(10)是最合算的。VARCHAR类型的实际长度是它的值的实际长度+2。为什么"+2"呢?这一个字节用于保存实际使用了多大的长度。这个可以在MSDN上找到:
varchar [ ( n | max ) ]
Variable-length, non-Unicode string data. n defines the string length and can be a value from 1 through 8,000. max indicates that the maximum storage size is 2^31-1 bytes (2 GB). The storage size is the actual length of the data entered + 2 bytes.
因此,从空间上考虑,用varchar合适;从效率上考虑,用char合适,关键是根据实际情况找到权衡点。
TEXT、NCHAR、NVARCHAR、NTEXT
TEXT
- text存储可变长度的非Unicode数据,最大长度为2^31-1(2,147,483,647)个字符,2GB。
NCHAR、NVARCHAR、NTEXT
- 这三种从名字上看比前面三种多了个"N"。和char、varchar比较起来,nchar、nvarchar最多存储4000个字符,不论是英文还是汉字;而char、varchar最多能存储8000个英文,4000个汉字。可以看出使用nchar、nvarchar数据类型时不用担心输入的字符是英文还是汉字,较为方便,但在存储英文时数量上有些损失。
所以一般来说,如果含有中文字符,用nchar/nvarchar,如果纯英文和数字,用char/varchar。