[MSSQL] 欄位開立(1) - nvarchar, varchar, nchar, char的抉擇

欄位開立(1) - nvarchar, varchar, nchar, char的抉擇

每次到了開立欄位,總是覺得型別很陌生嗎?

這邊跟大家分享一些建議與數據

首先我們必須先了解一下:nvarchar, varchar, nchar, char到底差別在哪?

 

1.var,意思是可變動的,因為欄位長度可變動,所以會額外花費2Byte去儲存地址

nvarchar:可變動長度的nchar

varchar:可變動長度的char

2.n,支援UNICODE UCS-2字元,因為萬國編碼(支援中文字),所以1字儲存2Byte

nvarchar:可變動長度的nchar

nchar:固定長度的char

3.總的來說:

(1) var因為額外儲存地址,讀取時會先去抓資料,會比非var來的略慢

效能:(nvarchar, varchar) < (nchar, char)

(2) n因為1字2Byte,所以正常會花費2倍儲存空間

儲存體:(nvarchar, nchar) >> (varchar, char)

4.實際儲存空間:

char(n):n Byte

varchar(n):(n + 2) Byte  --2Byte記錄地址

nchar(n):(2 * n) Byte

nvarchar(n):(2 * n + 2) Byte

5.建議:

確認一定長度,且只會有英數字:char

確認一定長度,且可能會用非英數以外的字元:nchar

長度可變動,且只會有英數字:varchar

長度可變動,且可能會用非英數以外的字元:nvarchar

6.案例:以校務行政系統的學年(Year)和學期(Semester)為例。

以通用的角度來說,我們常會以nvarchar來做為欄位的開立 (因為不用想)

但以學年來說,正常運行是不會有超過999年的學年,也不會有學期10以上的情況

因此適合開立固定長度且非UNICODE的欄位:char

(註:數字型別 tinyint也是 1Byte,可能是更棒的選擇,但這邊僅作String型別的比較)

以下舉例做比較:

學年

 

Year(如:103)

空間計算

儲存空間

每1,000筆儲存空間

nvarchar(10)

(3 * 2) + 2

8 Byte

8000 Byte

nchar(3)

(3 * 2)

6 Byte

6000 Byte

char(3)

3

3 Byte

3000 Byte

 

學期

Semester(如:1)

空間計算

儲存空間

每1,000筆儲存空間

nvarchar(10)

(1 * 2) + 2

4 Byte

4000 Byte

nchar(1)

(1 * 2)

2 Byte

2000 Byte

char(1)

1

1 Byte

1000 Byte

 


CREATE TABLE #table_nvarchar(Year nvarchar(10), Semester nvarchar(10)) 
CREATE TABLE #table_nchar(Year nchar(3), Semester nchar(1)) 
CREATE TABLE #table_char(Year char(3), Semester char(1)) 
GO   

--輸入1000筆測試用資料 
INSERT INTO #table_nvarchar VALUES('103', '1') 
INSERT INTO #table_nchar VALUES('103', '1') 
INSERT INTO #table_char VALUES('103', '1') 
GO 1000   

--比較效能 
SELECT * FROM #table_nvarchar 
SELECT * FROM #table_nchar 
SELECT * FROM #table_char 
GO   

--查詢後,清除暫存表 
DROP TABLE #table_nvarchar 
DROP TABLE #table_nchar 
DROP TABLE #table_char 
GO

 

image

效能:char > nchar = ncharvar

 

參考資料:

String and Binary Types

 

創用 CC 授權條款
本著作係採用創用 CC 姓名標示-相同方式分享 4.0 國際 授權條款授權,文章歡迎轉載,請註明出處,謝謝~~~