SQL Serverでのvarcharのサイジングに関する現在のベストプラクティスは何ですか?


12

ストレージとパフォーマンスの両方の観点から、varchar列の大きさを決定する最良の方法を理解しようとしています。

パフォーマンス
私の研究から、それはそうですvarchar(max)は、本当に必要な場合にのみ使用してください。つまり、列が8000文字以上を収容する必要がある場合、1つの理由はインデックス作成の欠如です(ただし、一般にvarcharフィールドでのインデックス作成には少し疑いがあります。ただし、DBの原則はかなり新しいので、それが根拠がないかもしれません。 )および圧縮(より多くのストレージの問題)。実際、クエリは可能な最大サイズを考慮しなければならないため、一般的に人々はvarchar(n).... oversizingを行うときに必要なものだけを使用することを推奨しているようです。しかし、エンジンはデータの実際の平均サイズの推定値として、示されたサイズの半分を使用することも述べられています。これは、データから平均サイズを決定し、それを2倍にし、それをnとして使用する必要があることを意味します。ただし、変動性が非常に低いがゼロではないデータの場合、これは、最大サイズの最大2倍のサイズ変更を意味します。洞察をいただければ幸いです。

ストレージ
実際のストレージは実際のデータに制限されていることを念頭に置いて、行内ストレージと行外ストレージのしくみについて読んだ後、nの選択はストレージにほとんどまたはまったく影響がないように思えます(それがすべてを保持するのに十分な大きさであることを確認してください)。varchar(max)を使用しても、ストレージに影響はありません。代わりに、可能であれば、各データ行の実際のサイズを〜8000バイトに制限することが目標になる場合があります。それは物事を正確に読んでいますか?

コンテキスト
一部の顧客データは少し変動するため、通常、必要な列よりも少し幅を広く(たとえば15〜20%大きく)します。他に特別な考慮事項があるかどうか疑問に思っていました。たとえば、一緒に仕事をしている人から、2 ^ n-1サイズを使用するように言われました(ただし、それを証明するものは見つかりませんでした。

最初のテーブル作成について話している。新しいテーブルの送信を開始し、サンプルデータ(または最初の本番データセットのみ)を送信することをお客様から言われます。これを見て、データを保持するためのテーブルを作成します。将来のインポートとサンプルの内容を処理できるように、テーブルを作成します。ただし、特定の行は長くなるようにバインドされているため、それらをパディングします。

問題はどれくらいか、そして技術的なガイドラインはありますか?


MongoDBは、ドキュメントに2 ^ nのディスク割り当てを使用します。SQL Serverはこの戦略を使用しません。
Michael Green

回答:


19

特定のデータ型に関係なく、格納するアプリケーションリクエストを格納できる必要があります。実際に保存される最大サイズよりも小さいものを指定することはできません。

また、さまざまな理由で保存される実際の最大サイズよりも長い列の長さを指定する必要はありませんし、必要もありません。クエリのメモリ割り当て、最大行サイズがいっぱいになる可能性があり、列を追加する余地がない未来など

真の可変長文字列とバイナリ列には、固定長データ型(文字列/バイナリ/数値/日付/など)が行うストレージの影響はありません(ただし、これらの影響の一部は、データ圧縮またはSPARSE列定義の使用によって無効にすることができます)オプション)。ただし、指摘したように、直接的なストレージの影響がない場合でも、クエリに必要なメモリを過大に見積もることによるパフォーマンスの影響は依然として存在します。

賢明である。必要なものだけを使用してください。近い将来に列の長さを長くする必要がある可能性が高い場合は、考慮を払うことができますが、サイズを小さくするよりも列のサイズを大きくする方が簡単であることに注意してください。はい、一部の作業が関係しますが、その作業は単に「潜在的な」ものであるため、オーバーサイズのパフォーマンスへの影響は「実際の」ものですが、多くの場合、実際に必要なものではなく、実際に必要なものに基づいて列を定義するのが最善です。 -sortaは将来必要になるかもしれないと思います。話されている多くの変更は決して起こらない、そしてしばしば必要とされる変更は予見できない。あなたが知っていることで行ってください。

代わりに、可能であれば、各データ行の実際のサイズを〜8000バイトに制限することが目標になる場合があります。

あなたがここで何を得ているのか正確にはわかりません。SQL Serverでは、物理的には8000バイトをわずかに超えます。LOB型を使用して- 、VARCHAR(MAX)NVARCHAR(MAX)VARBINARY(MAX)XMLおよび非推奨TEXTNTEXTIMAGE種類が-その最初のページサイズの制限を超えて行くのを可能に、それが原因で種類に応じて、ポインタ(16バイト以上を配置し、そして依存するだけですMAXタイプを使用するときに、行外に格納される値のサイズ)。データページの実際の物理的な制限は変更されませんでした。

あなたの目標は、不完全な値が意味を失ったり、下流で問題を引き起こしたりすることなく、アプリやビジネスが保存または破壊する必要のないものを保存するために、最小限の物理スペースを使用することです。12,000文字のモノを格納する必要がある場合は、それVARCHAR(MAX)が必要であるため使用してください。電話番号や郵便番号を保存している場合、それを使用するのVARCHAR(100)は賢明ではなく、無責任VARCHAR(MAX)です。

一部の顧客データは少し変動するため、通常、必要な列よりも少し広い列(たとえば、15〜20%大きい)にします。他に特別な考慮事項があるかどうか疑問に思っていました。

すべてのシステムに、変動するデータが少なくともありませんか?個人の名前を保存するシステムは、資格がありますよね?名前の長さにはかなり大きなばらつきがあります。そして、プリンスのような人がその名前をシンボルに変更して、長さではないまったく別の問題が発生します。これはまさに物事です。

しかし、悪魔の擁護者を少し演じるには、「必要なものより15〜20%大きい」値を実際に必要な値にするにはどうすればよいでしょうか。新しい列を追加することについての議論があり、誰かが50文字を提案したとすると、他の誰かが「まあ、20%多いのは60なので、誰かが60を持っているかもしれないので60をやりましょう」と言います。顧客が60を持っている可能性があるというのが本当である場合、60は実際に必要な値であり、常にそうでしたが、50は常に間違っていました。

もちろん、次の理由により、データのソースに関して何らかの指示があった場合に役立ちます。

  1. 「URL」を1024にし、誰かが1060を必要とする場合、それは1060である必要があります(同様に、URLを作成しVARCHAR、ドメイン名で許可されているUnicode文字をめちゃくちゃにしているという苦情があった場合、それはである必要がありますNVARCHAR)。だが
  2. 誰かが、その後、500文字制限のコメント欄に1000個の文字を追加したい場合は、それはまだのみ必要な 500人々が(コメントでそれほど冗長;-)私にとって大きな挑戦することができますすることが、ProductSKUよりよいすべてに適合するために十分に大きいこと顧客のSKUの。

最初のテーブル作成について話している。新しいテーブルの送信を開始し、サンプルデータ(または最初の本番データセットのみ)を送信することをお客様から言われます。これを見て、データを保持するためのテーブルを作成します。将来のインポートとサンプルの内容を処理できるように、テーブルを作成します。ただし、特定の行は長くなるようにバインドされているため、それらをパディングします。問題はどれくらいか、そして技術的なガイドラインはありますか?

あなたは作っている多くのここでの仮定を。確かにいくつかのフィールド大きくなるかもしれません。しかし、再び、そうではないかもしれません。または、一部が小さくなる可能性があります。一部は非UnicodeからUnicodeに変更できます(世界が小さくなっていることを認識し、姓に基本的なASCII /米国英語の文字のみが含まれるとは想定できない場合)。または、フィールドの送信を停止することもできます。または、将来的に1つ以上のフィールドを追加できます。これと他のものの任意の組み合わせ。では、なぜVARCHAR列だけに焦点を合わせるのでしょうか?現在INT値を送信していて、1〜2年で最大値に達し、送信を開始した場合はBIGINTどうなりますか?値0〜5の「ステータス」フィールドがある場合はどうなるでしょうか。INTこれは、成長を可能にするために「パディング」されていますが、おそらくそれをすべきでしょうTINYINTか?

安全に予測できる唯一のことは、顧客データがどのように変化するかを予測しようとすることは、正しいというよりも間違っていることが多いということです。そして、正しいことは運/偶然の問題です(運がなければ、宝くじをプレイしてください;)。

したがって、ガイドラインは次のとおりです。

  1. 答えられない質問に答えようとすることに時間とエネルギーを無駄にしないでください。
  2. 代わりに、顧客の実際のデータに関するできるだけ多くの情報を取得することに焦点を当て、それを実行してください(つまり、データ主導の意思決定;-)。

すでにサンプルデータがあります。ただし、お客様の連絡先情報(電話またはメール、あるいはその両方)もご確認ください。それらに連絡してください!彼らにデータ仕様を尋ねます(ちょうどあなたのシステムと同じように、彼らのシステムに現在あるデータは35の最大長を持っているかもしれませんが、彼らのシステムはそれをとして定義されてVARCHAR(50)おり、彼らのシステムはその長さまで受け入れます。 50)。また、変更の短期的な計画や、それらのデータ型(タイプやサイズ)があるかどうかを尋ねます。


1
私はソロモン、@ Aristotle2600に同意します-ただし、a とaの違いに関する質問に対する私の回答を見てさらに検討する必要がありますvarchar(255)varchar(256)
Max Vernon

おかげで、こんな感じになってしまい、「必要なものだけを使う」というのは、リソース管理全体としてはいい習慣だと思います。ただし、一部の顧客データは少し変動するため、通常、必要な列よりも少し広い列、たとえば15〜20%大きい列を作成します。他に特別な考慮事項があるかどうか疑問に思っていました。たとえば、一緒に仕事をしている人から、2 ^ n-1サイズを使用するように言われました(ただし、それを証明するものは見つかりませんでした...)。しかし、物事をできるだけ小さく保つこと以外に何もないように思えます。
aristotle2600

1
@ aristotle2600「2 ^ n-1」の適用方法はわかりませんが、それでも質問する必要があります。必要以上に大きなものを作成することは理論的には可能ですか?15〜20%大きいサイズ、壊れないようにするために必要なサイズではないでしょうか。;-)。データのソースをより明確に示した方がいいと思います。a)「URL」を1024にし、誰かが1060を必要とする場合、1060にする必要がありますが、b)誰かが1000を追加する場合、 500文字制限のコメントフィールドにcharsを入力した場合でも、必要なのは500文字だけです。コメントに入力できる人数は少なくなりますが、製品のSKUは十分に大きくする必要があります。
ソロモンルツキー

@ aristotle2600ここにあなたのコメントのいくつかを質問に追加しました。私はまた、私の回答の最後に項目を追加しました:)
ソロモンRutzky

回答ありがとうございます!はい、名前と住所は変動します。ますます増加する20%のパラドックスに関しては、私はあなたが何を意味するのか理解していますが、私は最初のテーブル作成について話しています。新しいテーブルの送信を開始し、サンプルデータ(または最初の本番データセットのみ)を送信することをお客様から言われます。これを見て、データを保持するためのテーブルを作成します。将来のインポートとサンプルの内容を処理できるように、テーブルを作成します。ただし、特定の行は長くなるようにバインドされているため、それらをパディングします。問題はどれくらいか、そして技術的なガイドラインはありますか?
aristotle2600
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.