2009-03-04 73 views
59

當我們必須使用Unicode類型時,是否有規則?當我們必須在SQL Server中使用NVARCHAR/NCHAR而不是VARCHAR/CHAR嗎?

我已經看到,大多數歐洲語言(德語,意大利語,英語,...)在VARCHAR列的相同數據庫中都很好。

我要尋找類似:

  1. 如果你有中國 - >使用NVARCHAR
  2. 如果你有德語和阿拉伯語 - >使用NVARCHAR

什麼整理的服務器/數據庫?

我不想總是使用NVARCHAR喜歡這裏建議 What are the main performance differences between varchar and nvarchar SQL Server data types?

回答

96

要使用NVARCHAR是當你有在同一列不同語言的真正原因,你需要解決在T-SQL中的列無需解碼,要能夠看到數據「原生地」在SSMS中,或者你想在Unicode上進行標準化。

如果您將數據庫視爲啞存儲,則完全可以在VARCHAR(例如UTF-8)中存儲寬字符串和不同的(甚至可變長度)編碼。問題出現在您嘗試編碼和解碼時,尤其是如果代碼頁對於不同的行不同。這也意味着SQL Server將無法輕鬆處理數據,以便在T-SQL中(可能可變)編碼的列中查詢。

使用NVARCHAR可以避免所有這些。

我會推薦NVARCHAR的任何列將有用戶輸入的數據,它是相對不受限制的。

我會推薦VARCHAR用於任何列,這是一個天然的鑰匙(如汽車牌照,SSN,序列號,服務標籤,訂單號,機場呼號等)或用戶輸入,但非常有限(如電話號碼)或代碼(ACTIVE/CLOSED,Y/N,M/F,M/S/D/W等)。這些絕對沒有理由使用NVARCHAR。

因此,對於一個簡單的規則:

VARCHAR保證時,被約束 NVARCHAR否則

+2

>>當你在同一列有不同的語言....就是這樣! – 2009-11-09 09:56:37

3

希臘將需要N個列類型UTF-8:αβγ)

10

你應該使用NVARCHAR任何時候你有存儲多個語言。我相信你必須將它用於亞洲語言,但不要引用它。

如果您以俄語爲例,並將其存儲在varchar中,則只要您定義了正確的代碼頁,就會出現問題。但是讓我們說你使用默認的英文SQL安裝,那麼俄文字符將不會被正確處理。如果你使用的是NVARCHAR(),它們將被正確處理。

編輯

好讓我引用MSDN和梅比我要具體,但你不想來存儲一個以上的代碼頁中varcar列,而你可以,你不應該

當您處理存儲在炭 文本數據,VARCHAR VARCHAR(最大值),或文本數據類型,考慮 的 最重要的限制是,從一個單一的 代碼頁唯一信息可以通過驗證 系統。 (您可以存儲來自 多個代碼頁的數據,但建議不使用 。)使用 驗證和存儲數據的確切代碼頁取決於列的歸類上的 。如果 列級別排序規則未定義爲 ,則使用數據庫 的排序規則。爲了確定代碼頁 一個用於給定列,你 可以使用COLLATIONPROPERTY 函數,如下面的 代碼示例:

這裏的一些:

這個例子說明了 許多語言環境(如格魯吉亞語和 印地語)沒有代碼頁,因爲它們的 是僅Unicode編碼。這些 排序規則是不適合使用的CHAR,VARCHAR或 文本數據類型

所以格魯吉亞或印地文真的需要被存儲爲nvarchar的 列。阿拉伯語也是一個問題:

您可能會遇到的另一個問題是 無法在不 所有要 支持字符都包含在代碼 頁面來存儲數據。在很多情況下,Windows認爲 的一個特定代碼頁是「最佳 合適」代碼頁,這意味着有 不能保證您可以依靠 代碼頁來處理所有文本;它是 只是最好的一個可用。這方面的一個例子 是阿拉伯文字: 它支持廣泛的語言陣列, 包括俾路支,柏柏爾,波斯語, 克什米爾,哈,吉爾吉斯,普什圖語, 信德語,維吾爾人,烏爾都語,等等。所有的 這些語言具有額外 字符超出阿拉伯文 語言作爲Windows代碼 頁1256定義。如果你試圖存儲在具有阿拉伯 整理,該字符的 非Unicode列 這些額外的字符被 轉換成問號。

當您使用Unicode時,請記住一些事項,儘管您可以在單個列中存儲不同的語言,但只能使用單個歸類進行排序。有些語言使用拉丁字符,但不能像其他拉丁語言那樣排序。口音就是一個很好的例子,我不記得這個例子,但是有一種東歐語言,其Y不像英語Y那樣排序。然後是西班牙語用戶在h之後排序。

總而言之,在處理內部化問題時必須處理所有問題。我認爲從一開始就使用Unicode字符比較容易,避免了額外的轉換並節省空間。因此我先前的發言。

+3

>>您應該在任何時候使用NVARCHAR來存儲多種語言 這是不正確的。德語和意大利語以及英語與VARCHAR列在同一個表格中很適合。 請更具體 – 2009-03-04 23:07:19

+0

請參閱http://www.sqlservercentral.com/Forums/Topic19439-9-1.aspx和http://stackoverflow.com/questions/7207590/sql-server-case-collat​​ion-issue舉例與dz和ly在匈牙利。 – 2012-09-13 17:18:01

2

喬希說: 」 ......事情要記住,當你使用Unicode儘管可以將不同的語言在一個列中只能使用單個排序規則進行排序,有些語言使用拉丁字符,但不能像其他拉丁語言那樣排序,口音就是一個很好的例子,我不記得這個例子,但是有一種東歐語言,其Y不像英語Y那樣排序。然後是西班牙語用戶在西班牙語後面排序,然後在h之後排序。「

我是西班牙本土揚聲器和「CH」是不是一個字母,但兩個「C」和「h」和西班牙的字母是這樣的: ABCDEFGHIJKLMNñopqrstuvwxyz 後,我們不希望「CH」「 h「但是」i「 除英文字母外,英文字母與英文字母相同或HTML」& ntilde;「

亞歷

0

TL; DR;
Unicode - (nchar,nvarchar和ntext)
非Unicode - (char,varchar和text)。

From MSDN

的排序規則在SQL Server中提供了排序規則,案例和重音 敏感度性質爲您的數據。與 字符數據類型(如char和varchar)一起使用的排序規則規定了代碼頁 以及可爲該數據類型表示的相應字符。

假設你正在使用默認的SQL排序SQL_Latin1_General_CP1_CI_AS那麼下面的腳本應該打印出來,你可以適應VARCHAR因爲它使用一個字節來存儲一個字符(256個),如果你沒有看到它的所有符號列表打印 - 你需要NVARCHAR

declare @i int = 0; 
while (@i < 256) 
begin 
print cast(@i as varchar(3)) + ' '+ char(@i) collate SQL_Latin1_General_CP1_CI_AS 
print cast(@i as varchar(3)) + ' '+ char(@i) collate Japanese_90_CI_AS 
set @i = @i+1; 
end 

如果更改排序規則可以說,日本你會發現,所有的怪異歐洲字母變成正常和一些符號到?馬克。

Unicode是將代碼點映射到字符的標準。由於 旨在涵蓋世界上所有語言的所有字符,因此不需要使用不同的代碼頁來處理不同的字符集。如果存儲反映多個 語言的字符數據,請始終使用Unicode數據類型(nchar,nvarchar和ntext) 而不是非Unicode數據類型(char,varchar和text)。

否則你的排序會變得奇怪。

相關問題