web-dev-qa-db-ja.com

SQL ServerでVARCHAR / CHARの代わりにNVARCHAR / NCHARを使用する必要があるのはいつですか?

Unicode型を使用する必要がある場合のルールはありますか?

私は、ほとんどのヨーロッパ言語(ドイツ語、イタリア語、英語など)がVARCHAR列の同じデータベースで問題ないことを見てきました。

私は次のようなものを探しています:

  1. 中国語-> NVARCHARを使用している場合
  2. ドイツ語とアラビア語がある場合-> NVARCHARを使用する

サーバー/データベースの照合はどうですか?

ここで提案されているように常にNVARCHARを使用したくありません varcharとnvarchar SQL Serverデータ型の主なパフォーマンスの違いは何ですか?

65
Peter Gfader

NVARCHARを使用する本当の理由は、同じ列にdifferent言語があり、デコードせずにT-SQLの列をアドレス指定する必要がある場合、データを「ネイティブに表示できるようにする」ことです。またはSSMSで、またはUnicodeで標準化する場合。

データベースをダムストレージとして扱う場合、ワイド文字列と異なる(可変長さえ)エンコーディングをVARCHAR(たとえばUTF-8)に保存することは完全に可能です。問題は、特にコードページが行ごとに異なる場合に、エンコードおよびデコードを試みるときに発生します。また、SQL Serverは、T-SQL内で(潜在的に可変)エンコードされた列に対してクエリを実行するために、データを簡単に処理できないことを意味します。

NVARCHARを使用すると、このすべてを回避できます。

比較的制約のないユーザー入力データが含まれる列には、NVARCHARをお勧めします。

通常、標準または法律または規則によって定義および制約されている自然なキー(車両のナンバープレート、SSN、シリアル番号、サービスタグ、注文番号、空港コールサインなど)である列にはVARCHARをお勧めします。また、ユーザーが入力した非常に制約された(電話番号など)またはコード(ACTIVE/CLOSED、Y/N、M/F、M/S/D/Wなど)のVARCHAR。それらにNVARCHARを使用する理由はまったくありません。

簡単なルールの場合:

それ以外の場合、NVARCHARが制約されることが保証されている場合はVARCHAR

109
Cade Roux

複数の言語を格納する必要があるときはいつでもNVARCHARを使用する必要があります。アジア言語に使用する必要があると思いますが、引用してはいけません。

たとえば、ロシア語をvarcharに保存する場合の問題は、正しいコードページを定義する限り問題ありません。しかし、デフォルトの英語のSQLインストールを使用すると、ロシア語の文字は正しく処理されません。 NVARCHAR()を使用していた場合、それらは適切に処理されます。

編集

わかりました [〜#〜] msdn [〜#〜] そして特定の特定のかもしれませんが、varcar列に複数のコードページを保存したくない場合は、してはいけない

Char、varchar、varchar(max)、またはtextデータ型に格納されているテキストデータを扱う場合、考慮すべき最も重要な制限は、単一のコードページからの情報のみがシステムによって検証できることです。 (複数のコードページからデータを保存できますが、これは推奨されません。)データの検証と保存に使用される正確なコードページは、列の照合順序によって異なります。列レベルの照合が定義されていない場合、データベースの照合が使用されます。特定の列に使用されるコードページを決定するには、次のコード例に示すように、COLLATIONPROPERTY関数を使用できます。

ここにいくつかあります:

この例は、グルジア語やヒンディー語などの多くのロケールがUnicodeのみの照合であるため、コードページがないことを示しています。これらの照合は、char、varchar、またはtextデータ型を使用する列には適していません

したがって、グルジア語またはヒンディー語は、nvarcharとして保存する必要があります。アラビア語も問題です。

発生する可能性のある別の問題は、サポートしたいすべての文字がコードページに含まれていない場合にデータを保存できないことです。多くの場合、Windowsは特定のコードページを「最適な」コードページと見なします。つまり、コードページに依存してすべてのテキストを処理できるという保証はありません。それは単に利用可能な最高のものです。この例はアラビア語のスクリプトです。バルチ語、ベルベル語、ペルシア語、カシミール語、カザフ語、キルギス語、パシュト語、シンド語、ウイグル語、ウルドゥー語など、幅広い言語をサポートしています。これらのすべての言語には、Windowsコードページ1256で定義されているアラビア語の文字を超える追加の文字があります。これらの余分な文字をアラビア語照合を持つ非Unicode列に保存しようとすると、文字は疑問符に変換されます。

Unicodeを使用している場合は、1つの照合順序を使用して並べ替えることができる単一の列にさまざまな言語を格納できますが、留意する必要があります。ラテン文字を使用しているが、他のラテン言語のように分類されない言語がいくつかあります。アクセントはこの良い例です。例を思い出すことはできませんが、Yが英語のYのようにソートされていない東ヨーロッパの言語がありました。その後、スペイン語のユーザーがhの後にソートされることを期待するスペイン語のchがあります。

全体として、内在化を扱う際に対処しなければならないすべての問題があります。私の意見では、最初からユニコード文字を使用し、余分な変換を避け、スペースをヒットする方が簡単です。したがって、以前の私の声明。

10
JoshBerke

ギリシャ語では、N列タイプのα-8γにUTF-8が必要です。

3
cherouvim

Josh氏は次のように述べています。「.... Unicodeを使用している場合、1つの列に異なる言語を格納できますが、1つの照合順序でのみソートできます。ラテン文字を使用するが、アクセントはこの良い例です。例を思い出すことはできませんが、東ヨーロッパの言語があり、そのYは英語のYのようにソートされていませんでした。 hの後。」

私はスペイン語を母国語としています。「ch」は文字ではなく、2つの「c」と「h」で、スペイン語のアルファベットは次のとおりです。abcdefghijklmnñopqrstuvwxyzアルファベットは、ñまたはHTMLの「ñ」を除いて英語と同じです。

アレックス

2
Alex

TL; DR;
Unicode nchar、nvarchar、およびntext)
非Unicode-(char、varchar、およびtext)。

---(MSDNから

SQL Serverの照合順序は、データの並べ替え規則、大文字と小文字、およびアクセントの区別のプロパティを提供します。 charやvarcharなどの文字データ型で使用される照合順序は、そのデータ型で表現できるコードページと対応する文字を決定します。

デフォルトのSQL照合SQL_Latin1_General_CP1_CI_ASを使用していると仮定すると、次のスクリプトはVARCHARに収まるすべてのシンボルを出力する必要があります。印刷されたリストにある-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データ型(char、varchar、およびtext)ではなく、常にUnicodeデータ型(nchar、nvarchar、およびntext)を使用してください。

そうしないと、ソートがおかしくなります。

0