web-dev-qa-db-ja.com

MySQL VARCHARとTEXTデータ型の違いは何ですか?

バージョン5.0.3(VARCHARを65,535バイトにできるようになり、末尾のスペースの切り捨てを停止した)以降、これら2つのデータ型の間に大きな違いはありますか?

私は 相違点のリスト を読んでいましたが、注意すべき2つだけは次のとおりです。

BLOB列とTEXT列のインデックスの場合、インデックスプレフィックス長を指定する必要があります。 CHARおよびVARCHARの場合、プレフィックス長はオプションです。セクション7.5.1「列インデックス」を参照してください。

そして

BLOB列とTEXT列にDEFAULT値を含めることはできません。

では、TEXTデータ型に対するこれらの2つの制限のため、なぜvarchar(65535)ではなくそれを使用するのでしょうか。どちらか一方のパフォーマンスに影響はありますか?

19
Derek Downey

divided 基本的な問題(パフォーマンスの違いがある)を説明するいくつかの情報にリンクされていますが、一方が常に他方より優れていると言うのは簡単ではありません。 (それ以外の場合は、両方を使用する理由はありません。)また、MyISMでは、VARCHARの64kの最大サイズはフィールドごとではなく、レコードごとです。

基本的に、データベースレコードに文字列を格納する方法は4つあります。

  1. 固定長
  2. Cスタイルの文字列(文字列の最後にNULLまたは同様の文字が付いている)
  3. Pascalスタイルの文字列(長さを示すために数バイト、次に文字列)
  4. ポインタ(文字列を別の場所に格納)

MyISMはVARCHARに#3に似たものを使用し、文字列の先頭をレコードに格納し、残りの文字列を他の場所に格納するTEXTのハイブリッドアプローチを使用します。 InnoDBはVARCHARに似ていますが、完全なTEXTフィールドをレコードの外側に格納します。

1&4を使用すると、レコードの内容は常に同じ長さになるため、文字列は不要で、その後に文字列が必要な場合はスキップする方が簡単です。 #2と#3はどちらも短い文字列には悪くありません...#2はマーカーを探し続ける必要がありますが、#3は先にスキップできます...文字列が長くなると、この特定の用途では#2が悪化します場合。

文字列を実際に読み取る必要がある場合は、レコードを読み取る必要があるため、#4の方が遅くなります。その後、データベースの処理方法に応じて、ディスクの他の場所に格納されている可能性のある文字列を読み取ります。 #1は常に非常に単純明快で、#2は文字列が長くなるほど悪化しますが、#3は非常に小さな文字列の#2より少し悪いですが、長くなるほど改善されます。

次に、ストレージ要件があります...#1は常に固定長であるため、ほとんどの文字列が最大長でない場合は膨らむ可能性があります。 #2には1バイト余分にあります。 #3は通常、最大長= 255の場合は2バイト、最大長が64kの場合は4バイト追加されます。 #4には、ポインターの長さと、通常は#3のルールがあります。

MySQL 5.1内の特定の実装については、 MyISM状態のドキュメント

  • 真のVARCHARタイプのサポート。 VARCHAR列は、1バイトまたは2バイトに格納された長さで始まります。
  • VARCHAR列を持つテーブルは、固定または動的な行の長さを持っている場合があります。
  • テーブルのVARCHAR列とCHAR列の長さの合計は、最大64KBになる場合があります。

While InnoDBの場合

  • レコードヘッダーの可変長部分には、NULL列を示すビットベクトルが含まれています。 NULLになる可能性のあるインデックスの列数がNの場合、ビットベクトルはCEILING(N/8)バイトを占有します。 (たとえば、NULLの可能性がある9から15の列がある場合、ビットベクトルは2バイトを使用します。)NULLの列は、このベクトルのビット以外のスペースを占有しません。ヘッダーの可変長部分には、可変長列の長さも含まれます。各長さは、列の最大長に応じて、1バイトまたは2バイトになります。インデックス内のすべての列がNOT NULLであり、固定長である場合、レコードヘッダーには可変長部分がありません。
  • NULL以外の可変長フィールドごとに、レコードヘッダーには1バイトまたは2バイトの列の長さが含まれます。列の一部が外部でオーバーフローページに格納されている場合、または最大長が255バイトを超え、実際の長さが127バイトを超える場合にのみ、2バイトが必要になります。外部に格納された列の場合、2バイトの長さは、内部に格納された部分の長さと、外部に格納された部分への20バイトのポインターの長さを示します。内部部分は768バイトなので、長さは768 + 20です。 20バイトのポインタは、列の実際の長さを格納します。

...

データベースを扱うときの他の多くのことと同様に、ニーズに最適なものがわからない場合は、同様のデータと使用法でそれをベンチマークし、それらがどのように動作するかを確認してください。

13
Joe

SELECTが一時的なテーブルを作成する必要がある場合(結果をソートするなど)、それはMEMORYテーブルまたはMyISAMテーブルを作成します。 MEMORYの方が効率的です。 MEMORYには制限があります。1つは、TEXTとBLOBを許可しないことです。したがって、SELECT mayは、VARCHARよりもTEXTの方が実行速度が遅くなります。

2
Rick James