在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,000。max 指示最大存儲大小是 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'
如果查看表可以看到:
仔細的數一數可以發現后面是4個空格,nchar_Col也是4個空格。這點說明對於定長類型char,nchar如果長度不足的話,在后面補充空格。
因為帶有var,所以長度變了,后面不會有空格。
結論:使用長度固定的類型的時候,可能要做Trim操作,當然也可以選擇RTrim,因為是在后面補充空格的。
2:執行下面的Sql語句:
insert into TestTable(char_Col,nchar_Col,nvarchar_Col,varchar_Col)
values('王王王王王','王王王王王','王王王王王','王王王王王')
結果如下:
char和varchar的長度是5,但是它們存儲的是非Unicode字符,采用一個字節的形式來存儲數據。
Nchar 和nvarchar 的長度也是5,但是存儲的是Unicode字符,采用兩個字節來存儲數據,也就是是說對於任何字符,都采用兩個字節來存儲,不管是數字還是字母,或者是英文,總之任何字符都采用兩個字節來儲存。
在上面的例子中,”王”是中文,所有的中文都用兩個字節表示,
所以上面的Sql語句就代表 select 10個字節,10個字節,10個字節,10個字節。
我們的表定義設置了所以的n為5,這里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')
結果:
一個中文2個字符,所以’王王a’ 一共5個字符。
修改代碼為:
insert into TestTable(char_Col,nchar_Col,nvarchar_Col,varchar_Col)
values('王王a','123456','王王王王王','12345')
和上面的不同是將nchar_Col加了個6.
結果:
為什么?
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”,”ab王d”.一個漢字兩個字節,這些字符串的字節全部都是5
關於何時使用char,varchar,nchar,nvarchar,msdn給了一部分建議:
· 如果列數據項的大小一致,則使用 char。
· 如果列數據項的大小差異相當大,則使用 varchar。
· 如果列數據項大小相差很大,而且大小可能超過 8,000 字節,請使用 varchar(max)。
· 如果需要支持Unicode,使用nchar,nvarchar
在早期的Sql Server 版本中,如果要存儲大量的字符串,可以采用ntext,text,image 數據類型,不過微軟建議:
Uniqueidentifier:16字節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 值。