iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 6
4
Modern Web

淺談資料庫&ASP.net&C# 入門系列 第 6

[iT鐵人賽Day6]SQL Server 資料型態 char varchar nchar nvarchar

選擇適合的資料型態

建立資料表時需要先選擇欄位的資料型態,而當要輸入文字存入資料時,要使用哪種資料型態呢?

在SQL Server大致上有char varchar nchar nvarchar text ntext 這6種可以選擇。

不過這次我要介紹的是較常用的4種char varchar nchar nvarchar的資料型態。

那麼這4種的差別在哪裡呢?

char varchar nchar nvarchar

仔細觀察以上4種型態從字面上的差別只在有無var以及有無n,

接下來將要來介紹 char varchar nchar nvarchar 的差別,幫助選擇自己適合的資料型態。

所以var跟n是什麼呢?

定長與變長

定長(沒有var):文字的長度固定,當輸入的數據長度沒有達到指定的長度時將自動以英文空格在其後面填充,讓長度達到相對應的長度。

變長(有var):表示是實際存儲空間是變長的,也就是說當輸入的數據長度沒有達到指定的長度時不會在後面填充空格。(不過text所存儲的也是可變長的)。

舉個例子來說,現在資料表有兩個欄位:

rocket1 char(10)
rocket2 varchar(10)
存入相同的資料「HiIU」

rocket1 會自動在「HiIU」後面補空白,存滿10 Bytes。
rocket2 會根據資料長度變更儲存空間,「HiIU」共四個英文字符,所以則存了4 Bytes。

使用varchar相對節省空間。

Unicode或非Unicode

在資料庫中,每個英文字符的儲存空間只需要一個 1 Byte,但若是非英文字及符號,如中文、泰文、日文、韓文等非英文字符,則需要 2 Byte來儲存。
如果英文與中文同時存在,由於占用空間數不同,容易造成混亂,導致讀取出來的字符串是亂碼。所以就要使用Unicode字符集(N)。

Unicode(有n):所有的文字都用2 Byte來儲存,即使是英文字也是使用2 Byte來儲存,就可以解決中英文字符集不兼容的問題。

非Unicode(沒有n):文字是英文字符就是1 Byte;非英文字符就是使用2 Byte來儲存。

舉例來說,一樣有兩個欄位:
rocket1 varchar(50)
rocket2 nvarchar(50)
存入相同的資料「我愛TsungHua」

rocket1: 我愛 = 22= 4 Byte ; TsungHua =81= 8 Byte ,所以總共4+8=12 Byte的儲存空間。

rocket2:「我愛TsungHua」共10個字,所以儲存空間為10*2=20 Byte。

雖然rocket2較佔儲存空間,但若儲存的資料不限於英文,建議都以n開頭的欄位型態為主,避免亂碼。

所以總結

有var的:在存不固定長度的資料時,較省空間。
有n的:支援Unicode,不過儲存的資料會大兩倍(全部都英文字的話啦)。

然後建議開資料表欄位時,要以儲存的資料為考量,
建議:

char 存資料有固定長度,並且都為英文數字。
nchar 存資料有固定長度,但不確定是否都是英文數字。
varchar 存資料沒有固定長度,並且都為英文數字。
nvarchar 存資料沒有固定長度,且不確定是否皆為英文數字。

整理一下

char(n) 定長,n 必須是一個介於 1 和 8000 之間的數值,最多8000個英文字,4000個非英文字,儲存大小為 n 個位元組。

nchar(n) 定長,n 的值必須介於 1 與 4000 之間。儲存大小為 n 位元組的兩倍。

varchar(n) 變長,n 必須是一個介於 1 和 8000 之間的數值,可存儲4000個字,無論英文還是非英文,儲存大小為輸入資料的位元組的實際長度。

nvarchar(n) 變長,n 的值必須介於 1 與 4000 之間,位元組的儲存大小是所輸入字元個數的兩倍。

text(n) 變長,非Unicode數據,最大長度為2^31-1(2,147,483,647)個字符。

ntext(n) 變長,最大字串長度為 2^30 - 1 (1,073,741,823) 位元組的可變長度 Unicode 資料。 儲存體大小 (以位元組為單位) 是輸入字串長度的兩倍。


上一篇
[iT鐵人賽Day5]主索引鍵與外部索引鍵
下一篇
[iT鐵人賽Day7] -SQL Server資料庫基本操作手動創立資料表
系列文
淺談資料庫&ASP.net&C# 入門36
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
CynthiaChuang
iT邦新手 5 級 ‧ 2019-09-07 00:26:46

(已瞎)(戴墨鏡)

捲毛蔡 iT邦新手 4 級 ‧ 2019-09-16 10:16:55 檢舉

( ̄∇ ̄)( ̄∇ ̄)( ̄∇ ̄)( ̄∇ ̄)( ̄∇ ̄)

1
YoChen
iT邦研究生 1 級 ‧ 2019-09-09 14:26:57

若以資料查詢的效能來說,使用varchar相對節省空間,索引速度自然較快。

應該是char的索引速度較快~

rocket1: 我愛 = 22= 4 Byte ; TsungHua = 81 = 8 Byte ,所以總共4+8=12 Byte的儲存空間。

裡面的*都變成斜體標記了~XDDD

捲毛蔡 iT邦新手 4 級 ‧ 2019-09-16 10:12:09 檢舉

感謝Yo大的提醒,確實是char的索引速度較快>< 我一直以為索引速度跟儲存空間有關,看來是無關的

4
小朱
iT邦新手 4 級 ‧ 2019-09-13 18:20:42

這裡沒有提到 max 這個長度,長度設為 max 時可存到 2GB (同 text/ntext 的長度)。
之所以會有 max 長度,是因為用 text/ntext 型態的欄位取資料的方法異於一般的作法,現在實務上都已經盡量避免使用 text/ntext (還有一個image) 這三種型態了。

捲毛蔡 iT邦新手 4 級 ‧ 2019-09-16 10:15:41 檢舉

感謝S大詳細的說明>< 看來我還不夠了解資料型態哈哈,我會再補充的,感謝您。

0
grtert
iT邦新手 5 級 ‧ 2020-02-18 00:17:59

謝謝分享!

0

我要留言

立即登入留言