web-dev-qa-db-ja.com

ここでvarcharよりもvarbinaryを使用する利点は何ですか?

少し前に、SQLServerでの階層/バージョン番号の並べ替えについて質問しました。 ( SQL Serverクエリを使用して「バージョン番号」列を一般的に並べ替える方法 )。

提出された回答の中には ほぼ同じパズルでのTSQLコーディングチャレンジへのこのリンク がありました。

SQL2000ソリューションでは、作成者は2つのバリエーションを示しました。1つはvarcharを使用して返し、もう1つはvarbinaryを返します。著者は、なぜ彼がこれをしているのかを説明せずに説明します。

だから、私の質問は本当に、アプローチの違いの主な違い/利点(もしあれば)は何ですか?つまりなぜvarcharの代わりにvarbinaryを使用するのですか?

上記の記事で最もエレガントに要約されているため、コードの投稿は省略しました。

20
James Wiseman

Varbinaryデータは一般に元の文字列の一部あたりのvarcharのバイト数(10または11)よりも少ないバイト数(5)を消費することが予想されるため、非常に多数のコンポーネント、または発生した場合、より効率的になるはずです。

ただし、どちらかのソリューションを使用する場合は、両方を実装し(非常に短い)、実際のデータ(およびクエリパターン)に対してプロファイリングを試して、実際的な違いがあるかどうかを確認することをお勧めします(Iそうは思わないでしょう)。

(Crafty Steal):Martinが指摘しているように、照合を処理するために存在するすべてのコードが含まれるわけではないため、バイナリ比較はより効率的になります。 :-)

14

異なるvarchar列に異なる照合順序を使用して文字列を格納し、SQLクエリでそのような列を複数使用すると、SQLクエリで「照合順序の無効な組み合わせ」というエラーがスローされる場合があります。 (たとえば、互換性のない照合の2つの文字列を比較する場合、または異なる照合のデータを組み合わせた列に選択しようとする場合)。

ただし、クエリで「COLLATE」を指定すれば修正できます。例:

 WHERE 'A' COLLATE latin1_general_ci = 'A' COLLATE latin1_general_ci 

しかし、これはあなたが持っているかもしれないどんなINDEXも打ち負かします。

「照合の無効な組み合わせ」エラーを防ぐために、varbinaryを使用できます。

varchar列にマルチバイト照合が使用されている場合、varbinaryはvarcharよりも少ないスペースを使用します。 (バイナリ文字列には文字セットと照合順序はありません。バイナリ文字列は単なるバイト値のシーケンスです)。

***ところで、文字セットは記号とエンコーディングのセットです。照合は、文字セット内の文字を比較するための一連のルールです https://dev.mysql.com/doc/refman/5.7/en/charset-general.html

ただし、マルチバイト文字セット(ex、utf8またはucs2)ではなくシングルバイト文字セット(ex、latin1)を選択した場合、varbinaryとvarcharの両方のスペース要件は同じです。

妥当性チェックがない場合、VARBINARYはVARCHARよりも優れています。たとえば、デフォルトの文字セットがUTF8の場合、これは不正です。

CREATE TABLE t9 (s1 VARCHAR(5));
INSERT INTO t9 VALUES (0xF4808283);

ただし、文字セットは重要ではないため、これは合法です。

CREATE TABLE t10 (s1 VARBINARY(5));
INSERT INTO t10 VALUES (0xF4808283);

したがって、VARCHARは「照合」とVARBINARY比較バイトを使用して文字を比較します。ほとんどの照合は「大文字と小文字を区別しない」ため、大文字と小文字は等しいと見なされます。 varbinaryは照合を使用しないため、varbinaryの場合、検索操作では常に大文字と小文字が区別されます。

4
sudip