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



When Must We Use Nvarchar Nchar Instead Varchar Char Sql Server



解決:

NVARCHARを使用したい本当の理由は、 違う 同じ列の言語、デコードせずに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を使用する理由はまったくありません。

したがって、単純なルールの場合:

制約があることが保証されている場合はVARCHAR、そうでない場合はNVARCHAR




複数の言語を保存する必要があるときはいつでもNVARCHARを使用する必要があります。私はあなたがそれをアジアの言語のために使わなければならないと信じます、しかしそれについて私を引用しないでください。

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

編集

さて、MSDNとmaybeeを引用させてください。具体的には、varcar列に複数のコードページを格納したくないのですが、そうすべきではありません。

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

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

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

したがって、ジョージアン様式またはヒンディー語は、実際にはnvarcharとして保存する必要があります。アラビア語も問題です:

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

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

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


最も賛成された2つの答えはどちらも間違っています。 「異なる/複数の言語を保存する」とは何の関係もありません。次のようなスペイン語の文字をサポートできますñと英語、ただ一般的varcharフィールドとLatin1_General_CI_AS照合、例:

短縮版
あなたは使用する必要がありますNVARCHAR /NCHARはいつでもENCODING、これはによって決定されますフィールドの照合は、必要な文字をサポートしていません。
また、SQL Serverのバージョンに応じて、特定のを使用できますのようなコレクションLatin1_General_100_CI_AS_SC_UTF8は、SQL Server2019以降で使用できます。この照合を設定するVARCHARフィールド(またはテーブル/データベース全体)は、UTF-8そのフィールドのデータを保存および処理するためのエンコード、完全なサポートを可能にするUNICODE文字、したがってそれに含まれるすべての言語。


完全に理解するには:
私が説明しようとしていることを完全に理解するには、UNICODE、エンコーディングと照合はすべてあなたの頭の中で非常に明確です。そうでない場合は、まず、「UNICODE、ENCODING、COLLATION、UTF-8とは何か、およびそれらがどのように関連しているか」セクションと提供されているドキュメントリンクに関する私の謙虚で簡略化された説明をご覧ください。また、私がここで言うことはすべてに固有のものですMicrosoft SQL Server、およびデータの保存と処理方法char /ncharとvarchar /nvarcharフィールド。

MSSQLServerデータベースに固有のテキストを保存したいとします。それはInstagramのコメントかもしれません '私はstackoverflowが大好きです! '。
平易な英語の部分はASCIIでも完全にサポートされますが、絵文字もあるので、UNICODE標準、私たちは必要ですこのUnicode文字をサポートするENCODING。

MSSQLServerは何を決定するための照合ENCODINGはで使用されますchar /nchar /varchar /nvarcharフィールド。だから、多くの人が考えるのとは違って、照合 ではありません データの並べ替えと比較についてだけでなく、エンコーディング、そして結果として: データの保存方法!

そう、 照合で使用されるエンコーディングをどのように知ることができますか? これとともに:

SELECT COLLATIONPROPERTY( 'Latin1_General_CI_AI'、 'C​​odePage')AS [CodePage] --1252を返します

この単純なSQLは、のWindowsコードページ照合。 NSWindowsコードページは、への別のマッピングにすぎません。エンコーディング。のためにLatin1_General_CI_AI照合を返しますWindowsコードページコード1252、それはにマップしますWindows-1252エンコーディング。
だから、varchar列、Latin1_General_CI_AI照合、このフィールドは、を使用してデータを処理しますWindows-1252ENCODINGであり、このエンコーディングでサポートされている文字のみを正しく格納します。

確認するとWindows-1252 ENCODING仕様Windows-1252の文字リストでは、このエンコーディングは絵文字をサポートしていないことがわかります。それでも試してみると、次のようになります。

varcharフィールドでの照合とエンコードが原因で、誤って保存されたUNICODE文字を含むテキスト

OK、どうすればこれを解決できますか? 実際、それは状況次第で、それは良いことです!

NCHAR /NVARCHAR

SQL Server 2019の前は、私たちが持っていたのはNCHARとNVARCHARフィールド。一部の人は彼らがUNICODEフィールド。 それは間違いです! 。繰り返しますが、それはフィールドのCOLLATIONおよびSQLServerバージョン。 Microsoftの「ncharおよびnvarchar(Transact-SQL)」ドキュメントでは、次のように完全に指定されています。

SQL Server 2012(11.x)以降、補足文字(SC)対応の照合が使用される場合、これらのデータ型はすべての範囲のUnicode文字データを格納し、UTF-16文字エンコードを使用します。非SC照合が指定されている場合、これらのデータ型は、UCS-2文字エンコードでサポートされている文字データのサブセットのみを格納します。

つまり、たとえばSQL Server 2008R2のように2012年より古いSQLServerを使用する場合、これらのフィールドのエンコードでは、のサブセットをサポートするUCS-2エンコーディングUNICODE。ただし、SQL Server 2012以降を使用し、持っている照合補足文字が有効になっている場合、フィールドを使用する場合よりもUTF-16ENCODING、それは完全にサポートしますUNICODE。


しかし、待ってください、もっとあります! UTF-8を使用できるようになりました!!

CHAR /VARCHAR

SQL Server 2019以降、 使用できますCHAR /VARCHAR フィールドとまだ完全にサポートUNICODEを使用してUTF-8エンコーディング!!!

Microsoftの「charおよびvarchar(Transact-SQL)」ドキュメントから:

SQL Server 2019(15.x)以降、UTF-8対応の照合を使用すると、これらのデータ型はすべての範囲のUnicode文字データを格納し、UTF-8文字エンコードを使用します。非UTF-8照合が指定されている場合、これらのデータ型は、その照合の対応するコードページでサポートされている文字のサブセットのみを格納します。

繰り返しますが、言い換えると、たとえばSQL Server 2008R2のように2019年より古いSQLServerを使用する場合は、前に説明した方法を使用したエンコード。ただし、SQL Server 2019以降を使用し、のような照合Latin1_General_100_CI_AS_SC_UTF8の場合、フィールドは次を使用しますUTF-8ENCODINGは、これまでで最も使用され、効率的なエンコーディングであり、すべてのUNICODE文字。


ボーナス情報:

OPの観察について 「ほとんどのヨーロッパ言語(ドイツ語、イタリア語、英語など)は、同じデータベースのVARCHAR列で問題ないことがわかりました。」 、それがなぜであるかを知ることは素晴らしいことだと思います:

最も一般的なCOLLATIONS、デフォルトのもののようにLatin1_General_CI_AIまたはSQL_Latin1_General_CP1_CI_ASエンコードはWindows-1252 forvarcharフィールド。そのドキュメントを見ると、以下をサポートしていることがわかります。

英語、アイルランド語、イタリア語、ノルウェー語、ポルトガル語、スペイン語、スウェーデン語。さらに、ドイツ語、フィンランド語、フランス語もあります。そして、IJ文字を除くオランダ語

しかし、前に言ったように、それは言語ではなく、絵文字の例に示されているように、どの文字をサポート/保存することを期待するか、または「リチウム電池の電気抵抗は0.5Ωです」のような文です。平易な英語、およびギリシャ文字/文字「オメガ」(オーム単位の抵抗の記号)は、によって正しく処理されませんWindows-1252エンコーディング。

結論:

だから、あります!使用する場合char /ncharとvarchar /nvarcharは、サポートする文字と、サポートする文字を決定するSQLServerのバージョンによって異なります。コレクション、したがって利用可能なエンコーディング。




UNICODE、ENCODING、COLLATION、UTF-8とは何ですか、またそれらはどのように関連していますか
注:以下のすべての説明は 簡略化 。これらの概念に関するすべての詳細を知るには、提供されているドキュメントのリンクを参照してください。

  • UNICODE -統一され整理されたテーブル内のすべての文字を規制することを目的とした標準、規則です。この表では、すべての文字に一意の番号があります。この番号は一般的にキャラクターと呼ばれますコードポイント。
    UNICODEはエンコードではありません!

  • エンコーディング -文字とバイト/バイトシーケンス間のマッピングです。したがって、エンコーディングは、文字をバイトに「変換」するために使用され、逆にバイトから文字に変換するためにも使用されます。最も人気のあるものの中にはUTF-8、ISO-8859-1、Windows-1252およびASCII。あなたはそれを「変換テーブル」と考えることができます(私はここで本当に単純化されています)。

  • 照合 -それは重要です。 Microsoftのドキュメントでさえ、これが本来あるべきことを明確にしていません。照合は、データの並べ替え、比較、 そして保存されました! 。ええ、あなたはその最後のものを期待していなかったに違いありませんね!?上の照合SQL Serverは、その特定ので使用されるエンコーディングchar /nchar /varchar /nvarcharフィールド。

  • ASCIIエンコーディング -最初のエンコーディングの1つでした。それは両方の指標表です(独自の小さなバージョンのようにUNICODE)とそのバイトマッピング。したがって、バイトをにマップしませんUNICODEですが、バイトをそれ自体の文字のテーブルにマップします。また、常に7ビットのみを使用し、128の異なる文字をサポートします。大文字と小文字、数字、句読点、その他の限られた数の文字をすべてサポートするのに十分でした。 ASCIIの問題は、7ビットしか使用せず、ほとんどすべてのコンピューターが8ビットであったため、「探索」される文字の可能性がさらに128あり、誰もがこの「使用可能な」バイトを独自の文字テーブルにマップし始めたことです。 、さまざまなものを作成しますエンコーディング。

  • UTF-8エンコーディング -これは別ですENCODING、最も(最もではないにしても)使用されているものの1つ周りをエンコードします。可変バイト幅(仕様により、1文字の長さは1〜6バイト)を使用し、すべてを完全にサポートしますUNICODE文字。

  • Windows-1252エンコーディング -また、最も使用されているものの1つエンコード、SQLServerで広く使用されています。固定サイズなので、1文字1文字は常に1バイトです。また、さまざまな言語の多くのアクセントをサポートしていますが、既存のすべてをサポートしているわけではなく、サポートしていません。UNICODE。 だからあなたの次のような一般的な照合を持つvarcharフィールドLatin1_General_CI_ASはサポートしますNS、これは、ñ文字、それが支援を使用していない場合でもUNICODEエンコーディング。

資力:
https://blog.greglow.com/2019/07/25/sql-think-that-varchar-characters-if-so-think-again/
https://medium.com/@apiltamang/unicode-utf-8-and-ascii-encodings-made-easy-5bfbe3a1c45a
https://www.johndcook.com/blog/2019/09/09/how-utf-8-works/
https://www.w3.org/International/questions/qa-what-is-encoding

https://en.wikipedia.org/wiki/List_of_Unicode_characters
https://www.fileformat.info/info/charset/windows-1252/list.htm

https://docs.microsoft.com/en-us/sql/t-sql/data-types/char-and-varchar-transact-sql?view=sql-server-ver15
https://docs.microsoft.com/en-us/sql/t-sql/data-types/nchar-and-nvarchar-transact-sql?view=sql-server-ver15
https://docs.microsoft.com/en-us/sql/t-sql/statements/windows-collat​​ion-name-transact-sql?view=sql-server-ver15
https://docs.microsoft.com/en-us/sql/t-sql/statements/sql-server-collat​​ion-name-transact-sql?view=sql-server-ver15
https://docs.microsoft.com/en-us/sql/relational-databases/collat​​ions/collat​​ion-and-unicode-support?view=sql-server-ver15#SQL-collat​​ions

SQLServerのデフォルトの文字エンコード
https://en.wikipedia.org/wiki/Windows_code_page