關(guān)系數(shù)據(jù)庫在表中表示組織的數(shù)據(jù),這些表使用具有不同數(shù)據(jù)類型的列,允許它們存儲有效值。開發(fā)人員和DBA需要知道并理解每一列的適當(dāng)數(shù)據(jù)類型,以獲得更好的查詢性能。
本文將討論流行的數(shù)據(jù)類型VARCHAR()和NVARCHAR()、它們的比較以及SQLServer 中的性能評估。
SQL中的VARCHAR[ ( n | max ) ]
該VARCHAR數(shù)據(jù)類型表示非Unicode可變長度的字符串的數(shù)據(jù)類型。您可以在其中存儲字母、數(shù)字和特殊字符。
N表示以字節(jié)為單位的字符串大小。
VARCHAR數(shù)據(jù)類型列最多可存儲8000個非Unicode字符。
VARCHAR數(shù)據(jù)類型每個字符占用1個字節(jié)。如果您沒有明確指定N的值,則它需要1個字節(jié)的存儲空間。
注意:不要將N與表示字符串中字符數(shù)的值混淆。
以下查詢使用100個字節(jié)的數(shù)據(jù)定義VARCHAR數(shù)據(jù)類型。

它返回長度為17,因為每個字符1個字節(jié),包括一個空格字符。

以下查詢定義了沒有任何N值的VARCHAR數(shù)據(jù)類型。因此,SQLServer 將默認(rèn)值視為1個字節(jié),如下所示。

我們還可以通過CAST或CONVERT函數(shù)使用VARCHAR。例如,在下面的兩個示例中,我們聲明了一個長度為100字節(jié)的變量,然后使用了CAST運算符。
第一個查詢返回長度為30,因為我們沒有在CAST運算符VARCHAR數(shù)據(jù)類型中指定N。默認(rèn)長度為30。

但是,如果字符串長度小于30,則取字符串的實際大小。

SQL中的NVARCHAR[ ( n | max ) ]
所述NVARCHAR數(shù)據(jù)類型是用于Unicode的可變長度的字符數(shù)據(jù)類型。這里,N指的是國家語言字符集,用于定義Unicode字符串。您可以存儲非Unicode和Unicode字符(日語漢字、韓文等)。
N表示以字節(jié)為單位的字符串大小。
它最多可以存儲4000個Unicode和非Unicode字符。
VARCHAR數(shù)據(jù)類型每個字符占用2個字節(jié)。如果不為N指定任何值,則需要2個字節(jié)的存儲空間。
以下查詢使用100個字節(jié)的數(shù)據(jù)定義VARCHAR數(shù)據(jù)類型。

它返回36的字符串長度,因為NVARCHAR每個字符存儲占用2個字節(jié)。

與VARCHAR數(shù)據(jù)類型類似,NVARCHAR也有1個字符(2個字節(jié))的默認(rèn)值,而沒有為N指定顯式值。

如果我們使用CAST或CONVERT函數(shù)應(yīng)用NVARCHAR轉(zhuǎn)換而沒有任何顯式N值,則默認(rèn)值為30個字符,即60個字節(jié)。

以VARCHAR數(shù)據(jù)類型存儲Unicode和非Unicode值
假設(shè)我們有一個表,記錄來自電子購物門戶的客戶反饋。為此,我們有一個包含以下查詢的SQL表。

我們在這個表中插入幾個英語、日語和印地語的示例記錄。[Comment]的數(shù)據(jù)類型是VARCHAR,[NewComment]是NVARCHAR()。

查詢成功執(zhí)行,并在從中選擇一個值時給出以下行。對于第二和第三行,如果數(shù)據(jù)不是英語的,它就不能識別數(shù)據(jù)。

VARCHAR和NVARCHAR數(shù)據(jù)類型:性能比較
我們不應(yīng)在JOIN或WHERE謂詞中混合使用VARCHAR和NVARCHAR數(shù)據(jù)類型。它使現(xiàn)有索引無效,因為SQLServer 要求JOIN兩側(cè)的數(shù)據(jù)類型相同。如果不匹配,SQLServer 會嘗試使用CONVERT_IMPLICIT()函數(shù)進(jìn)行隱式轉(zhuǎn)換。
SQLServer 使用數(shù)據(jù)類型優(yōu)先級來確定目標(biāo)數(shù)據(jù)類型。NVARCHAR的優(yōu)先級高于VARCHAR數(shù)據(jù)類型。因此,在數(shù)據(jù)類型轉(zhuǎn)換期間,SQLServer 會將現(xiàn)有的VARCHAR值轉(zhuǎn)換為NVARCHAR。

現(xiàn)在,讓我們執(zhí)行兩個SELECT語句,根據(jù)它們的數(shù)據(jù)類型檢索記錄。

這兩個查詢都使用索引查找運算符和我們之前定義的索引。

現(xiàn)在,我們切換數(shù)據(jù)類型值以與WHERE謂詞進(jìn)行比較。第1列具有VARCHAR數(shù)據(jù)類型,但我們指定N'A'將其作為NVARCHAR數(shù)據(jù)類型。
類似地,col2是NVARCHAR數(shù)據(jù)類型,我們指定了引用VARCHAR數(shù)據(jù)類型的值“C”。

在查詢實際執(zhí)行計劃中,您得到一個索引掃描,SELECT語句有一個警告符號。

此查詢工作正常,因為NVARCHAR()數(shù)據(jù)類型可以同時具有Unicode和非Unicode值。
現(xiàn)在,第二個查詢使用索引掃描并在SELECT運算符上發(fā)出警告符號。

將鼠標(biāo)懸停在發(fā)出有關(guān)隱式轉(zhuǎn)換的警告的SELECT語句上。SQLServer 無法正確使用現(xiàn)有索引。這是由于VARCHAR和NVARCHAR數(shù)據(jù)類型的數(shù)據(jù)排序算法不同。
如果表有數(shù)百萬行,SQLServer必須做額外的工作并使用隱式數(shù)據(jù)轉(zhuǎn)換來轉(zhuǎn)換數(shù)據(jù)。它可能會對您的查詢性能產(chǎn)生負(fù)面影響。因此,在優(yōu)化查詢時應(yīng)避免混合和匹配這些數(shù)據(jù)類型。

結(jié)論
您應(yīng)該在適當(dāng)?shù)卦O(shè)計數(shù)據(jù)庫表及其列數(shù)據(jù)類型時查看您的數(shù)據(jù)要求。通常,VARCHAR數(shù)據(jù)類型可以滿足您的大部分?jǐn)?shù)據(jù)需求。但是,如果需要在列中同時存儲Unicode和非Unicode數(shù)據(jù)類型,則可以考慮使用NVARCHAR。但是,在做出最終決定之前,您應(yīng)該查看其性能影響、存儲大小。
審核編輯 :李倩
-
數(shù)據(jù)庫
+關(guān)注
關(guān)注
7文章
4044瀏覽量
68427 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4419瀏覽量
67670 -
數(shù)據(jù)類型
+關(guān)注
關(guān)注
0文章
237瀏覽量
14206
原文標(biāo)題:SQL Server 中的VARCHAR和NVARCHAR數(shù)據(jù)類型
文章出處:【微信號:哲想軟件,微信公眾號:哲想軟件】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
MySQL 慢 SQL 排查這件事,NineData 社區(qū)VS DBeaver/ Navicat 技術(shù)分析
基于凌羽派的OpenHarmony北向應(yīng)用開發(fā):ArkTS語法-數(shù)據(jù)類型和變量聲明
睿遠(yuǎn)研究院丨IO-Link規(guī)范解讀(十五):數(shù)據(jù)類型詳解
不用編程不用聯(lián)網(wǎng),快速實現(xiàn)PLC與數(shù)據(jù)庫雙向數(shù)據(jù)通訊的案例
LabVIEW 變體:萬能數(shù)據(jù)容器的藝術(shù)
使用NVIDIA Nemotron RAG和Microsoft SQL Server 2025構(gòu)建高性能AI應(yīng)用
C語言自動類型轉(zhuǎn)換
C語言強(qiáng)制類型轉(zhuǎn)換
SQL 通用數(shù)據(jù)類型
不用編程序無需聯(lián)外網(wǎng),將Rockwell羅克韋爾(AB)PLC的標(biāo)簽數(shù)據(jù)存入SQL數(shù)據(jù)庫
數(shù)據(jù)庫數(shù)據(jù)恢復(fù)—SQL Server數(shù)據(jù)庫被加密如何恢復(fù)數(shù)據(jù)?
大促數(shù)據(jù)庫壓力激增,如何一眼定位 SQL 執(zhí)行來源?
SQL Server中的VARCHAR和NVARCHAR數(shù)據(jù)類型
評論