web-dev-qa-db-ja.com

SQLの国別文字(NCHAR)データ型は実際には何ですか?

同様にCHAR(CHARACTER)およびVARCHAR(CHARACTER VARYING)、SQLはNCHAR(NATIONAL CHARACTER)およびNVARCHAR(NATIONAL CHARACTER VARYING)タイプ。一部のデータベースでは、これは文字(非バイナリ)文字列に使用するのに適したデータ型です。

  • SQL Serverでは、NCHARはUTF-16LEとして格納され、非ASCII文字を確実に格納する唯一の方法です。CHARはシングルバイトコードページのみです。

  • Oracleでは、NVARCHARはシングルバイト照合ではなく、UTF-16またはUTF-8として格納されます。

  • しかし、MySQLでは、NVARCHARVARCHARなので、違いはありません。どちらのタイプも、UTF-8または他の照合で格納できます。

では、実際にNATIONALは概念的には何を意味するのでしょうか。ベンダーのドキュメントでは、実際の理論的根拠ではなく、独自のDBMSが使用する文字セットについてのみ説明しています。一方、SQL92標準では、機能の説明はそれほど役に立ちませんが、NATIONAL CHARACTERは、実装で定義された文字セットに格納されます。実装で定義された文字セットに格納される単なるCHARACTERとは対照的です。これは、実装で定義された別の文字セットである可能性があります。か否か。

ありがとう、ANSI。タンシ。

すべての文字(非バイナリ)ストレージの目的でNVARCHARを使用する必要がありますか?現在人気のあるDBMSで、望ましくない処理を行ったり、キーワード(またはN''リテラル)?

50
bobince

この場合の「NATIONAL」は、異なる国籍に固有の文字を意味します。特に極東の言語は文字数が多いため、1バイトではすべてを区別するのに十分なスペースがありません。したがって、英語(ASCII)のみのアプリまたは英語のみのフィールドを使用している場合は、文字ごとに1バイトしか許可しない古いCHARおよびVARCHARタイプを使用して回避できます。

つまり、ほとんどの場合、NCHAR/NVARCHARを使用する必要があります。データで複数の言語をサポートする必要があると思わない場合でも、英語のみのアプリでも、外国語の文字を使用したセキュリティ攻撃を慎重に処理できる必要があります。

私の意見では、古いCHAR/VARCHARタイプが依然として優先される唯一の場所は、区別をサポートするSQL Serverのようなプラットフォームで頻繁に参照されるASCIIのみの内部コードとデータ(enumに相当するデータ) C++やC#などのクライアント言語。

14
Joel Coehoorn

一方、SQL92標準では、機能の説明はあまり役に立ちませんが、NATIONAL CHARACTERは実装で定義された文字セットに格納されていると述べています。実装で定義された文字セットに格納される単なるCHARACTERとは対照的です。これは、実装で定義された別の文字セットである可能性があります。か否か。

偶然にも、これはC++標準がcharwchar_tの間で行う「区別」と同じです。すべての言語とOSの組み合わせに独自の文字セットがある場合の、文字エンコーディングの暗黒時代の遺物。

すべての文字(非バイナリ)の格納目的でNVARCHARを使用する必要がありますか?

列の宣言されたタイプがVARCHARであるかNVARCHARであるかは重要ではありません。ただし、すべての文字の保存目的でUnicode(UTF-8、UTF-16、またはUTF-32のいずれか)を使用することが重要です。

それが望ましくないことをする現在人気のあるDBMSはありますか

はい:MS SQL Serverでは、NCHARを使用すると、(英語の)データが2倍のスペースを占めるようになります。残念ながら、 TF-8はまだサポートされていません

4
dan04

Oracleでは、データベースの文字セットはマルチバイト文字セットにすることができるため、そこにあらゆる種類の文字を格納できます。ただし、列の長さを適切に理解して定義する必要があります(BYTESまたはCHARACTERSのいずれかで)。 。

NVARCHARは、シングルバイトのデータベース文字セット(BYTEまたはCHARACTERサイズの列間の混乱の可能性を減らす)を使用し、マルチバイトとしてNVARCHARを使用するオプションを提供します。 こちら を参照してください。

私は主に英語のデータを扱うため、データベースの文字セットとしてマルチバイト文字セット(主にUTF-8)を使用し、NVARCHARは無視します。 1バイト文字セットであり、変換するには大きすぎる古いデータベースを継承した場合、NVARCHARを使用できます。しかし、私はそうしたくない。

3
Gary Myers