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


19

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

私は違いリストを読んでいたのですが、注意すべき点は2つだけです。

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

そして

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

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


1
データに65535以上の文字が必要な場合
BlackICE

ここでvarchar型とテキストの間のベンチマークについてのかなり良いのフォーラムのスレッドです:http://forums.mysql.com/read.php?24,105964,105964
分割

そこのリストは明確な詳細を実際にレイアウトするのに良い仕事をしており、既に列挙された違いのリストを持っているので、これがDBAに必要な質問の種類であるかどうかはわかりません。あなたが引用したリストとあなたが与えた理由がこの場合十分ではない理由はありますか?それ以外の場合は、VtCに行きます
jcolebrand

1
質問を更新しましたが、はっきりしない理由の1つは、一方のパフォーマンスが他方より優れていることです。他のそれほど明白でない理由があるかどうかわからない
デレクダウニー

それで、あなたが求めているのは、一方のパフォーマンス特性が他方のパフォーマンス特性であるということです。
jcolebrand

回答:


13

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

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

  1. 固定長
  2. Cスタイルの文字列(文字列の末尾にNULLまたは同様の文字でマークされている)
  3. パスカルスタイルの文字列(長さを示すために数バイト、次に文字列)
  4. ポインター(文字列を別の場所に保存)

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

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

実際に文字列を読み取る必要がある場合は、レコードを読み取る必要があるため、#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です。

しばらくInnoDBのための

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

...

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


スレッド分割リンクは、MySQLがブロブとテキストフィールドをインラインforums.mysql.com/read.php?24,105964,267596#msg-267596
Michael

1
Nitpick ...すべての実用的な目的のために、どちらのエンジンの行にも64KBの制限はありません。 LONGTEXTそしてLONGBLOB、その一例です。Cスタイルの文字列は、MySQLで使用されていません(私が知っていることです)。InnoDBは「ハイブリッド」アプローチを使用しますが、行サイズ、row_formatなどに応じてより複雑です。実際に一定の長さ(country_code、zip_codeなど)である場合を除き、「固定」長で文字列を保存することはほとんどお勧めできません。InnoDBには4がありROW_FORMATsます。テキストでは、そのうちの1つまたは2つについてのみ説明しています。
リックジェームズ

2

SELECTが(結果の並べ替えなどのために)一時テーブルを作成する必要がある場合、MEMORYテーブルまたはMyISAMテーブルを作成します。MEMORYはより効率的です。MEMORYには制限があります。1つは、TEXTとBLOBを許可しないことです。したがって、SELECT TEXTよりもVARCHARよりも遅くなる場合があります。

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