ユーザー間のメッセージを記録するMySQLのメッセージテーブルを持っています。典型的なIDとメッセージタイプ(すべて整数タイプ)は別として、私は実際のメッセージテキストをVARCHARかTEXTのどちらかとして保存する必要があります。フロントエンドの制限を3000文字に設定しました。これは、メッセージがこれよりも長くdbに挿入されないことを意味します。
VARCHAR(3000)とTEXTのどちらを使ってもよいという根拠はありますか? VARCHAR(3000)を書くだけでは直感に反すると感じることがあります。私はStack Overflowに関する他の似たような投稿をしてきましたが、この種の一般的なメッセージ保存に特有の見解を得るのは良いでしょう。
TEXT
とBLOB
は、実際のストレージの場所へのポインターを持つだけのテーブルで、テーブルから格納されます。
VARCHAR
はテーブルとインラインで格納されます。サイズが妥当であればVARCHAR
は速くなりますが、そのトレードオフはあなたのデータとあなたのハードウェアによりますので、あなたはあなたのデータで現実世界のシナリオをベンチマークしたいでしょう。
更新 VARCHAR
またはTEXT
がインラインで格納されるか、レコード外で格納されるかは、データサイズ、列サイズ、row_format、およびMySQLのバージョンによって異なります。 notは "text"と "varchar"のどちらに依存しますか。
ユーザー入力がどれくらいかかるか予測できますか?
VARCHAR(X)
ケース: ユーザー名、Eメール、国、件名、パスワード
テキスト
ケース: メッセージ、Eメール、コメント、フォーマットされたテキスト、HTML、コード、画像、リンク
MEDIUMTEXT
ケース: 大きいjson本体、短から中程度の長さの本、csv文字列
長いテキスト
事例: 教科書、プログラム、長年のログファイル、ハリーポッターと炎のゴブレット、科学研究記録
ベストプラクティスを明確にするためだけに:
テキストフォーマットのメッセージはほとんどの場合TEXTとして格納されるべきです(それらは任意に長いものになってしまいます)
文字列属性はVARCHAR(保存先ユーザー名、件名など)として格納する必要があります。
私はあなたがフロントエンドの制限を持っていることを理解しています、それはそうでないまで素晴らしいです。 * grin *トリックは、DBをそれに接続するアプリケーションとは別のものとして考えることです。 1つのアプリケーションがデータに制限を課しているからといって、データが本質的に制限されているわけではありません。
メッセージ自体が3000文字を超えないようにするのは、メッセージ自体とは何ですか?それが単なる任意のアプリケーション制約(たとえばテキストボックスなど)の場合は、データ層にTEXT
フィールドを使用します。
免責事項:私はMySQLの専門家ではありません...しかし、これは私が問題を理解していることです。
TEXTはmysqlの行の外側に格納されていると思いますが、VARCHARは行の一部として格納されていると思います。 mysql行には最大行長があります。そのため、VARCHARを使用して、1行に格納できる他のデータ量を制限できます。
また、VARCHARが行の一部を形成しているため、そのフィールドを検索するクエリはTEXTチャンクを使用するクエリよりもわずかに高速になると思われます。
簡単な答え: 実用的、パフォーマンス、またはストレージの違いはありません。
長い答え:
(MySQLでは)VARCHAR(3000)
(またはその他の大きな制限)とTEXT
の間に本質的な違いはありません。前者は3000 文字で切り捨てられます。後者は65535 バイトで切り捨てられます。 (私はbytesとcharactersを区別しています。なぜなら、文字は複数バイトをとることがあるからです。)
VARCHAR
の制限が小さい場合、TEXT
よりも優れた点がいくつかあります。
CHARACTER SET
に応じて、191、255、512、767、または3072などを意味します。INDEXes
はカラムのインデックス可能な大きさに制限があります。 (767または3072 バイト;これはバージョンと設定によって異なります)SELECTs
によって作成された中間テーブルは、MEMORY(速い)またはMyISAM(遅い)という2つの異なる方法で処理されます。 「大きな」列が含まれる場合は、遅い方の手法が自動的に選択されます。 (バージョン8.0で大幅な変更が加えられたため、この箇条書き項目は変更されることがあります。)TEXT
ではなく)すべてのVARCHAR
データ型は、MyISAMに直接ジャンプします。つまり、生成された一時テーブルの場合、TINYTEXT
は同等のVARCHAR
よりも自動的に悪化します。 (しかし、これは3番目の方向への議論を取ります!)VARBINARY
はVARCHAR
と同じです。 BLOB
はTEXT
と同じです。他の答えに反論する
最初の質問では、1つのこと(どのデータ型を使用するか)が尋ねられました。受け入れられた答えは他の何かに答えた(記録外の保存)。その答えは今時代遅れです。
このスレッドが開始されたときにandが応答したとき、InnoDBには2つの "行フォーマット"しかありませんでした。その後まもなく、さらに2つのフォーマット(DYNAMIC
とCOMPRESSES
)が導入されました。
TEXT
およびVARCHAR()
の格納場所は、データ型名ではなくsizeに基づいています。 updated の大きなtext/blobカラムのon/offレコードの保存については、 this を参照してください。
上記の答えは、主な問題を十分に主張しているわけではありません。
(SELECT t2.* FROM t1, t2 WHERE t2.id = t1.id ORDER BY t1.id)
一時テーブルが必要な場合があります。また、VARCHAR
フィールドが含まれる場合は、一時テーブル内のCHAR
フィールドに変換されます。テーブルにVARCHAR(65000)
フィールドを持つ500 000行と言う場合、この列だけで 6.5 * 5 * 10 ^ 9 byteが使用されます。このような一時テーブルはメモリ内で処理できず、ディスクに書き込まれます。その影響は壊滅的なものになると予想されます。
ソース(メトリック付き): https://nicj.net/mysql-text-vs-varchar-performance/ (これは、 "標準"(?)MyISAMストレージエンジンでのTEXT
とVARCHAR
の処理を指します。 InnoDBのように、他のものとは異なる場合があります。)
VARCHARとTEXTにはHUGEの違いがあります。 VARCHARフィールドにはインデックスを付けることができますが、TEXTフィールドにはできません。 VARCHAR型フィールドはインラインで保存され、TEXTはオフラインで保存されます。実際には、TEXTデータへのポインターのみがレコードに保存されます。
VARCHARを使用するよりも高速に検索、更新、または削除するためにフィールドのインデックスを作成する必要がある場合は、サイズに関係ありません。これら2つのデータ型は性質が異なるため、VARCHAR(10000000)がTEXTフィールドと同じになることはありません。
tEXTに行くよりも。
Varcharは電子メールアドレスのような小さなデータ用で、Textはニュース記事のようなもっと大きなデータ用です。Blobは画像などのバイナリデータ用です。
Varcharのパフォーマンスは、メモリから完全に実行されるため、より強力ですが、データがvarchar(4000)
のように大きすぎる場合は、そうではありません。
一方、テキストはメモリに固執せず、ディスクのパフォーマンスの影響を受けますが、テキストデータを別のテーブルで区切って左結合クエリを適用してテキストデータを取得することでこれを回避できます。
Blobははるかに遅いので、10000レコードのような10000イメージのようなデータがあまりない場合にのみ使用してください。
最高のスピードとパフォーマンスを得るには、次のヒントに従ってください。
名前、タイトル、Eメールにはvarcharを使用
大きなデータにテキストを使用
別の表にテキストを区切る
電話番号などのIDでLeft Joinクエリを使用する
Blobを使うつもりならば、Textと同じコツを当てはめてください。
これにより、データのサイズが10 Mを超え、サイズが最大10 GBまで保証されているテーブルでは、クエリに数ミリ秒かかることになります。