varcharとnvarcharの違いは何ですか?


1354

nvarcharマルチバイト文字をサポートしているだけですか?それが事実である場合、ストレージの懸念以外に、使用することには本当に意味がありvarcharsますか?


6
私はincomudroのポイントが好きです。それが、そもそもvarcharとnvarcharの違いを探るきっかけになりました。SQL Server dbに対するJavaアプリはmyBatisを使用します。myBatisはデフォルトで文字列をnvarcharとして送信するようです(それがどのように(またはそれが)オーバーライド可能かはまだわかりません)。単純なクエリは、選択対象の列をnvarcharではなくvarcharとして定義し、列のインデックスを無視していたため、大きなパフォーマンスの問題として現れていました。
Sean Read

回答:


1652

nvarchar列には、任意のUnicodeデータを格納することができます。varcharカラムは、8ビット・コードページに制限されています。varcharスペースを取らないため、これを使用する必要があると考える人もいます。これは正解ではないと思います。コードページの非互換性は苦痛であり、Unicodeはコードページの問題を解決します。最近の安価なディスクとメモリにより、コードページをいじくり回して時間を無駄にする理由は本当にありません。

最新のオペレーティングシステムと開発プラットフォームはすべて、内部的にUnicodeを使用しています。nvarcharではなくを使用varcharすることで、データベースの読み取りまたは書き込みを行うたびにエンコード変換を行うことを回避できます。変換には時間がかかり、エラーが発生しやすくなります。そして、変換エラーからの回復は重要な問題です。

ASCIIのみを使用するアプリケーションと接続している場合でも、データベースでUnicodeを使用することをお勧めします。OSとデータベースの照合アルゴリズムは、Unicodeでより適切に機能します。Unicodeは、他のシステムとインターフェース時に変換の問題を回避します。そして、あなたは未来に備えるでしょう。また、完全なUnicodeストレージのいくつかの利点を享受している間でも、維持しなければならないレガシーシステムのデータが7ビットASCIIに制限されていることを常に検証できます。


8
これはすばらしい情報です。最終的に選択がいずれかになると推測した場合、私はこれを正しく理解していますか?どのリソースの方が安いですか:プロセッサ+開発オーバーヘッドまたはストレージ?
Matt Cashatt、2012年

141
@MatthewPatrickCashatt-あなたはそれをそのように見ることができました。しかし、すべてのテキストデータがUnicode である栄光の世界を想像して、開発者が何かのエンコーディングを考える必要がなく、エラーのクラス全体が決して発生しない場合、そこにあることがわかります。本当に選択の余地はありません。
Jeffrey L Whitledge、2012年


8
@Martin Smith-これらの場合、varcharがもたらす(コンパクトストレージ)小さな利点が失われます。varcharは思ったよりも悪いと思います!
Jeffrey L Whitledge、2012

9
@PeterAllenWebb-UTF-16のサロゲートペアは文字であるかのようにUCS-2に格納できるため、任意のUnicodeデータを「格納」できます。これは、データの保存と取得に対して透過的に機能します。さて、あなたができないことは、BMPの外で信頼できるケース変換と比較を行うことですが、私はそれについて何も主張しませんでした。したがって、処理したいDesseretテキストがたくさんある場合は、データベースの外部で実行するのが最善です。しかし、それをそこに格納することは問題ありません。(もちろん、varcharもあなたを助けにはなりません!)
Jeffrey L Whitledge 2013年

259

varchar:可変長の非Unicode文字データ。データベース照合は、データがどのコードページを使用して格納されるかを決定します。

nvarchar:可変長のUnicode文字データ。比較はデータベース照合に依存します。

この知識を武器に、入力データに一致する方を使用してください(ASCII v。Unicode)。


5
varcharがUnicodeデータを格納できないような制限はありますか?すべて1と0です。中国語のコンテンツをvarcharとしてDBに正常に保存できます。ただし、そのUTF-8を指定するだけです。それはどのように機能しますか?
Nishant 2014

3
@Nishant遅い答え:もちろん、varcharにUTF-8を格納できますが、SQL Serverの文字列関数が壊れます。アプリケーション内ですべての検索/変換を実行する場合は、可能です(ただし、利点は何ですか?)。SSでサポートされているUnicodeエンコーディングはUCS-2であり(はい、SS2k16の前のUTF-16ではありません)、その文字列関数はそのエンコーディングでのみ機能します。ところで、インデックスはどうですか?任意のデータを保存する場合は、代わりにバイナリを使用することをお勧めします。
アドリアーノRepetti

はい、それは文字列検索関数を壊すだけです。
Nishant 2015

8
だから、あなたは知っています...それは「うまくいきません」。これは、floatをに格納してint「小数点以下が欠落していることを確認してください」のようなものです。しないでください。
user7116 2015

70

私は常にnvarcharを使用しています。これは、私が構築しているすべてのものが、私がそれに投げるほとんどすべてのデータに耐えることができるからです。私がnvarcharを使用したため、私のCMSシステムは誤って中国語を実行します。最近では、新しいアプリケーションは、必要なスペースの量を実際に気にする必要はありません。


25
新しいアプリはスペースの制限を考慮してはならないという考えはやや近視眼的であり、中規模から大規模のエンタープライズレベルでデータベースを扱ってきた人なら誰でも喜んであなたに話してくれるでしょう。
Frater、2010

60
tags2kの口の中に言葉を置く自由をとるには、より正確な声明は、「新しいアプリが国際化やその他の文字セットの問題よりも必要なスペースを重視する可能性がますます低くなることだ」と思います。
Cowan

1
「最近では、新しいアプリはどれも、必要なスペースの量を気にする必要はありません。」-無料のクラウドストレージを使用している場合を除き、有料プランは$でかなり高くなります(AppHarbor SQL Server共有プランを参照)。
2014

3
@ガンダースハウル!あなたはそこにいます。一般化されたステートメントは、一時的にしか正しくありません。コンピューティングは間違いなくスイングとラウンドアバウトのゲームです。私は間違いなく、Windows Azure CCPで使用している容量に関心があります。つまり、nvarcharよりもvarcharを「決して」使用しないということです。ああ、私は自分自身と矛盾しましたか?
rism 2014年

1
@rism、"never"少なくとも技術的には、での引用の使用と矛盾するリスクを取り除いたと思います。
Smandoli 2014年

30

Oracleのインストール方法によって異なります。インストールプロセス中に、NLS_CHARACTERSETオプションが設定されます。あなたはクエリでそれを見つけることができるかもしれませんSELECT value$ FROM sys.props$ WHERE name = 'NLS_CHARACTERSET'

NLS_CHARACTERSETがUTF8のようなUnicodeエンコーディングである場合、すばらしいです。VARCHARとNVARCHARの使用はほとんど同じです。今すぐ読むのをやめてください。それ以外の場合、またはOracleの文字セットを制御できない場合は、このまま読み進めてください。

VARCHAR —データはNLS_CHARACTERSETエンコーディングで格納されます。同じサーバー上に他のデータベースインスタンスがある場合、それらによって制限される可能性があります。設定を共有する必要があるため、その逆も同様です。このようなフィールドには、その文字セットを使用してエンコードできるデータだけを格納できます。たとえば、文字セットがMS-1252の場合、格納できるのは英語の文字、少数のアクセント付き文字、およびその他のいくつか(€や—など)だけです。あなたのアプリケーションはいくつかのロケールでのみ有用であり、世界の他の場所では動作できません。このため、それは悪い考えと見なされます。

NVARCHAR —データはUnicodeエンコーディングで保存されます。すべての言語がサポートされています。良いアイデア。

収納スペースはどうですか?文字セット/エンコーディングは特定のロケール用にカスタム設計されているため、VARCHARは一般に効率的です。NVARCHARフィールドは、皮肉なことにNLS設定に基づいて、UTF-8またはUTF-16エンコーディングで格納されます。UTF-8はアジア言語をサポートしながら、「西洋」言語に非常に効率的です。UTF-16はアジア言語に非常に効率的ですが、「西洋」言語もサポートしています。記憶域が心配な場合は、NLS設定を選択して、Oracleが適切にUTF-8またはUTF-16を使用するようにします。

処理速度はどうですか?ほとんどの新しいコーディングプラットフォームは、Unicodeをネイティブで使用しています(Java、.NET、さらには数年前のC ++ std :: wstringです!)。したがって、データベースフィールドがVARCHARの場合、読み取りまたは書き込みごとにOracleに文字セット間の変換を強制します。NVARCHARを使用すると、変換が回避されます。

結論:NVARCHARを使用してください!制限や依存関係を回避し、ストレージスペースには問題なく、通常はパフォーマンスにも最適です。


42
質問がsql-serverに関するものであることを除いて、これは本当に良い答えです。
刺激

21

nvarcharはデータをUnicodeとして格納するため、多言語データ(複数の言語)をデータ列に格納する場合は、Nバリアントが必要です。


16

私の2セント

  1. 正しいデータ型を使用しないと、インデックスが失敗する可能性があり
    ます。SQL Serverの場合:VARCHAR列にインデックスがあり、それにUnicode文字列を提示すると、SQL Serverはインデックスを使用しません。BigIntをSmallIntを含むインデックス付き列に提示するときにも同じことが起こります。BigIntがSmallIntになるほど小さい場合でも、SQL Serverはインデックスを使用できません。他の方法では、この問題は発生しません(インデックス付きBigIntまたはNVARCHAR列にSmallIntまたはAnsi-Codeを提供する場合)。

  2. データ型は、DBMS(データベース管理システム)によって異なる場合があります。
    すべてのデータベースのデータ型はわずかに異なり、VARCHARはどこでも同じとは限らないことに注意してください。SQL ServerにはVARCHARとNVARCHARがありますが、Apache / DerbyデータベースにはVARCHARしかなく、VARCHARはUnicodeです。


ただし、コードを適切に記述している場合(つまり、パラメーター化されたクエリなどを使用している場合)、ポイント1の方がリスクは低くなります。
ポール、

14

主にnvarcharはUnicode文字を格納し、varcharは非Unicode文字を格納します。

「Unicode」とは、アラビア語、ヘブライ語、中国語、日本語など、他の多くの言語の文字を単一の文字セットでエンコードできる16ビット文字エンコード方式を意味します。

つまり、ユニコードは1文字あたり2バイトを使用して格納し、非ユニコードは1文字あたり1バイトのみを使用して格納します。つまり、ユニコードは、非ユニコードと比較して2倍の容量を格納する必要があります。


10

あなたが正しい。nvarcharUnicodeデータをvarchar格納し、1バイト文字データを格納します。すでに述べたように、ストレージの違い(のnvarchar2倍のストレージスペースが必要varchar)以外は、優先さnvarcharれる主な理由はvarchar国際化(つまり、他の言語で文字列を格納する)です。


10

それは場合によります。

OSがUnicode(現在のすべてのWindowsシステムと同様)で動作し、言語がUnicodeをネイティブでサポートするデスクトップアプリケーションを開発する場合(デフォルトの文字列はJavaまたはC#のようにUnicodeです)、nvarcharに移動します。

文字列がUTF-8として提供されるWebアプリケーションを開発し、言語がPHPであり、まだネイティブではUnicodeをサポートしていない場合(バージョン5.x)、varcharがおそらくより良い選択になります。


9

NVARCHAR店舗Unicodeは、あなたが使用することができますまた、照合の助けによって検討すべきであるVARCHAR、あなたの地元の言語のデータを保存して。

次のシナリオを想像してみてください。

DBの照合順序はペルシア語で、VARCHAR(10)データ型に'علی'(ペルシャ語でのAliの記述)などの値を保存します。問題はなく、DBMSは3バイトを使用して格納します。

ただし、データを別のデータベースに転送して正しい結果を表示したい場合、宛先データベースには、この例ではペルシア語であるターゲットと同じ照合が必要です。

ターゲット照合が異なる場合、ターゲットデータベースに疑問符(?)が表示されます。

最後に、ローカル言語を使用するための巨大なデータベースを使用している場合は、スペースを使いすぎずに場所を使用することをお勧めします。

デザインは異なる場合があると思います。作業する環境によって異なります。


8

私は答えを見ていたし、多くが使用することをお勧めしているように見えるnvarchar以上のvarcharスペースがもはや問題ではありませんので、少し余分なストレージのためのUnicodeを有効にするには害がないので、。ええと、これは、列にインデックスを適用したい場合には必ずしも当てはまりません。SQL Serverでは、インデックスを作成できるフィールドのサイズに900バイトの制限があります。したがって、があるvarchar(900)場合でも、インデックスを作成できますが、はできませんvarchar(901)。を使用するnvarcharと、文字数が半分になるため、最大までインデックスを作成できますnvarchar(450)。したがって、必要ないと確信している場合はnvarchar、使用しないことをお勧めします。

一般的に、データベースでは、いつでも拡張できるため、必要なサイズを維持することをお勧めします。たとえば、職場の同僚はnvarchar(max)、ストレージにまったく問題がないため、カラムに使用しても害はないと考えていました。後で、この列にインデックスを適用しようとすると、SQL Serverはこれを拒否しました。ただし、彼がから始めた場合は、varchar(5)この問題を修正するためにフィールド移行計画を立てる必要があるような問題がなければ、後でそれを必要なものに単純に拡張できたはずです。


7

nVarcharは、Unicode文字を格納するのに役立ちます。ローカライズされたデータを保存する場合に使用する方法です。


7

1バイトを使用して文字を格納する場合、256の可能な組み合わせがあり、それによって256の異なる文字を保存できます。照合は、文字と、それらを比較およびソートするためのルールを定義するパターンです。

Latin1(ANSI)である1252が最も一般的です。シングルバイト文字セットも、多くの言語で使用されるすべての文字を格納するには不十分です。たとえば、一部のアジア言語には数千の文字があるため、文字ごとに2バイトを使用する必要があります。

Unicode標準

複数のコードページを使用するシステムをネットワークで使用すると、通信の管理が困難になります。物事を標準化するために、ISOおよびUnicodeコンソーシアムはUnicodeを導入しました。Unicodeは2バイトを使用して各文字を格納します。つまり、65,536個の異なる文字を定義できるため、ほとんどすべての文字をUnicodeでカバーできます。2台のコンピューターがUnicodeを使用する場合、すべてのシンボルは同じ方法で表され、変換は必要ありません。これがUnicodeの背後にある考え方です。

SQL Serverには、文字データ型の2つのカテゴリがあります。

  • 非Unicode(char、varchar、およびtext)
  • Unicode(nchar、nvarchar、およびntext)

複数の国の文字データを保存する必要がある場合は、常にUnicodeを使用してください。


6

私はここで言わなければなりません(私はおそらく自分自身をスレートに開放するつもりだ!)確かに、すべての照合順序がすべてのときよりも、NVARCHAR実際役立つのは(そこにあることに注意してください!)VARCHAR依存するシステムとデータベース自体は同じです...?そうでない場合、照合変換はとにかく行われる必要があるため、とVARCHAR同じように実行可能になりNVARCHARます。

これに追加するために、SQL Server(2012より前)などの一部のデータベースシステムのページサイズは約です。8K。したがって、a TEXTNTEXTfield などで保持されていない検索可能なデータを格納する場合VARCHARは、8k分のスペースをすべて提供しますが、NVARCHAR4kのみを提供します(バイトを2倍、スペースを2倍)。

要約すると、どちらを使用するかは以下に依存すると思います。

  • プロジェクトまたはコンテキスト
  • インフラ
  • データベースシステム

6

SQL ServerのVARCHARデータ型とNVARCHARデータ型の違いを理解してください。ここでは、非常に説明的な方法で見ることができます。

一般にnvarcharはデータをUnicodeとして格納するため、多言語データ(複数の言語)をデータ列に格納する場合は、Nバリアントが必要です。


これは非常に便利なリンクですが、あなたの答えはそれ以上にはなりません:リンク。
RubberDuck 2014年

ckuhn203、これを見るように言うつもりはありません
Pradeep Kesharwani 14年

6

主な違いVarchar(n)とは、nvarchar(n)次のとおりです。 ここに画像の説明を入力してください

Varchar(可変長の非Unicode文字データ)サイズは最大8000です。1。可変長データ型です。

  1. 非Unicode文字を格納するために使用されます

  2. 文字ごとに1バイトのスペースを占める

ここに画像の説明を入力してください

Nvarchar:可変長Unicode文字データ。

1.可変長データ型

2.Unicode文字を格納するために使用されます。

  1. データはUnicodeエンコーディングで保存されます。すべての言語がサポートされています。(たとえば、アラビア語、ドイツ語、ヒンディー語などの言語)

6

ジェフリーLホイットリッジは47000レピュテーションスコアで、nvarcharの使用を推奨しています

〜33200の評判スコアを持つSolomon Rutzkyが推奨:常にNVARCHARを使用しないでください。これは非常に危険であり、多くの場合コストがかかる態度/アプローチです。

varcharとnvarcharのSQL Serverデータ型の主なパフォーマンスの違いは何ですか?

https://www.sqlservercentral.com/articles/disk-is-cheap-orly-4

そのような高い評判の両方の人、学習SQLサーバーデータベース開発者は何を選びますか?

選択に一貫性がない場合、パフォーマンスの問題に関する回答とコメントには多くの警告があります。

パフォーマンスに関するコメントpro / con nvarcharがあります。

パフォーマンスに関するコメントpro / con varcharがあります。

何百もの列を持つテーブルに対する特定の要件がありますが、それ自体はおそらく珍しいですか?

SQL * server 2012の8060バイトのテーブルレコードサイズ制限に近づかないように、varcharを選択しています。

私にとって、nvarcharの使用は、この8060バイトの制限を超えています。

また、関連するコードテーブルのデータ型を主要な中央テーブルのデータ型と一致させる必要があると考えています。

以前の経験豊富なデータベース開発者による南オーストラリア州政府のこの作業場所でのvarchar列の使用を見たことがあります。この場合、テーブルの行数は数百万以上になります(これらの非常に大きなnvarchar列がある場合、テーブル)、したがって、おそらく予想されるデータ行のボリュームはこの決定の一部になります。


1

nvarcharユニコード文字も許可varcharするため、コードをエラーなし(タイプの不一致)にするために比べて使用しても安全nvarcharです。whereSQL Serverクエリで条件を使用している場合、=演算子を使用していると、エラーが発生することがあります。これは、マッピング列がで定義されるためと考えられvarcharます。nvarcharこの問題でそれを定義した場合、私は起こりません。それでもvarchar、この問題に固執して回避するために、LIKEではなくキーワードを使用することをお勧めします=

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.