ストレージとパフォーマンスの両方の観点から、varchar列の大きさを決定する最良の方法を理解しようとしています。
パフォーマンス
私の研究から、varchar(max)は本当に必要な場合にのみ使用する必要があるようですようです。つまり、列が8000文字以上を収容する必要がある場合、1つの理由はインデックス付けの欠如です(ただし、一般的にvarcharフィールドのインデックス付けには少し疑いがあります。ただし、DBの原則はかなり新しいので、おそらくそれは根拠がありません。 )および圧縮(より多くのストレージの問題)。実際、クエリは可能な最大サイズを考慮しなければならないので、一般的に人々はvarchar(n).... oversizingを行うときに必要なものだけを使用することを推奨するようです。しかし、エンジンはデータの実際の平均サイズの推定値として、示されたサイズの半分を使用することも述べられています。これは、データから平均サイズを決定し、それを2倍にし、それをnとして使用する必要があることを意味します。ただし、変動性が非常に低いがゼロ以外のデータの場合、これは最大サイズの最大2倍のサイズ変更を意味します。洞察をいただければ幸いです。
ストレージ
行内ストレージと行外ストレージの仕組みについて読んだ後、実際のストレージは実際のデータに制限されていることを念頭に置いて、nの選択にはほとんどまたはまったく関係がないように見えますストレージ上(すべてを保持するのに十分な大きさであることを確認する以外に)。 varchar(max)を使用しても、ストレージに影響はありません。代わりに、可能であれば、各データ行の実際のサイズを〜8000バイトに制限することが目標になる場合があります。それは物事の正確な読みですか?
コンテキスト
お客様のデータの一部は少し変動するため、通常、必要な列よりも少し広い列、たとえば15〜20%大きい列を作成します。他に特別な考慮事項があるかどうか疑問に思っていました。たとえば、一緒に仕事をしている人から、2 ^ n-1サイズを使用するように言われました(ただし、それを証明するものは見つかっていません...)。
最初のテーブル作成について話している。新しいテーブルの送信を開始し、サンプルデータ(または最初の本番データセットのみ)を送信することをお客様から言われます。これを見て、データを保持するためのテーブルを作成します。将来のインポートとサンプルの内容を処理できるように、テーブルを作成します。ただし、特定の行は長くなるようにバインドされているため、パディングします。
問題はどれくらいか、そして技術的なガイドラインはありますか?
特定のデータ型に関係なく、保存するアプリケーションの要求を保存できる必要があります。実際に保存される最大サイズよりも小さいものを指定することはできません。
また、さまざまな理由で格納される実際の最大サイズよりも長い列の長さを指定する必要はありませんし、必要もありません。クエリのメモリ割り当て、最大行サイズがいっぱいになる可能性があり、列を追加する余地がない未来など.
真の可変長文字列とバイナリ列には、固定長データ型(文字列/バイナリ/数値/日付/など)が行うストレージの影響はありません(ただし、これらの影響の一部は、データ圧縮またはSPARSE
列の使用によって無効にすることができます定義オプション)。ただし、指摘したように、直接的なストレージの影響がない場合でも、クエリに必要なメモリを過大に見積もると、パフォーマンスに影響が生じます。
賢明である。必要なものだけを使用してください。近い将来に列の長さを長くする必要がある可能性が高い場合は、考慮事項を検討できますが、列のサイズを拡大する方が、サイズを縮小するよりも簡単であることに注意してください。はい、一部の作業が関係しますが、その作業は単に「潜在的」であるので、サイズ超過のパフォーマンスへの影響は「実際」ですが、多くの場合、実際に必要なものに基づいて列を定義するのが最善です。 -sortaは将来必要になるかもしれないと思います。話されている多くの変更は決して起こらない、そしてしばしば必要とされる変更は予見できない。あなたが知っていることで行ってください。
代わりに、可能であれば、各データ行の実際のサイズを〜8000バイトに制限することが目標になる場合があります。
あなたがここで何を得ているのか正確にはわかりません。 SQL Serverでは、物理的には8000バイトをわずかに超えます。 LOBタイプの使用— VARCHAR(MAX)
、NVARCHAR(MAX)
、VARBINARY(MAX)
、XML
、および非推奨のTEXT
、NTEXT
、およびIMAGE
タイプ—その最初のページサイズ制限を超えることができます、しかしそれはポインタを配置することによるものです(16バイト以上、タイプによって、およびMAX
タイプを使用するときに行外に格納される値のサイズによって)。データページの実際の物理的な制限は変更されませんでした。
あなたの目標は、不完全な値が意味を失ったり、下流で問題を引き起こしたりすることなく、アプリやビジネスが保存する必要のあるものを保存したり、壊したりせずに保存するために、最小限の物理スペースを使用することです。 12,000文字のものを格納する必要がある場合は、VARCHAR(MAX)
を使用してください。電話番号または郵便番号を保存している場合、VARCHAR(100)
を使用するのは賢明ではなく、VARCHAR(MAX)
を使用することは無責任です。
一部の顧客データは少し変動しているため、通常、必要な列よりも少し広い列(たとえば、15〜20%大きい)にします。他に特別な考慮事項があるかどうか疑問に思っていました。
すべてのシステムに、変動するデータが少なくともありませんか?個人の名前を保存するシステムがあれば、資格がありますよね?名前の長さにはかなり大きなばらつきがあります。そして、プリンスのような人が行って、名前をシンボルに変更すると、長さではないまったく別の問題が発生します。これがまさに物事です。
しかし、悪魔の擁護者を少し演じるには、「必要な値よりも15〜20%大きい」値を実際の必要とする値にするにはどうすればよいでしょうか。新しい列を追加することについての議論があり、誰かが50文字を提案し、他の誰かが「まあ、20%多いのは60なので、誰かが60を持っている可能性があるので60をやりましょう」と言います。顧客が60を持っている可能性があるというのが本当である場合、60は常にそうであったactualが必要な値であり、50は常に間違っていた。
もちろん、次の理由により、データのソースに関して何らかの指示があった場合に役立ちます。
VARCHAR
にして、ドメイン名で許可されているUnicode文字がめちゃくちゃになっているという不満を得る場合、NVARCHAR
にする必要がありました。 )、 だがProductSKU
は、お客様のすべてのSKUに対応できる大きさにする必要があります。最初のテーブル作成について話している。新しいテーブルの送信を開始し、サンプルデータ(または最初の本番データセットのみ)を送信することをお客様から言われます。これを見て、データを保持するためのテーブルを作成します。将来のインポートとサンプルの内容を処理できるように、テーブルを作成します。ただし、特定の行は長くなるようにバインドされているため、パディングします。問題はどれくらいか、そして技術的なガイドラインはありますか?
ここではたくさんを想定しています。確かにいくつかのフィールドmight大きくなります。しかし、再び、そうではないかもしれません。または、一部が小さくなる可能性があります。一部のユーザーは非UnicodeからUnicodeに変更できます(世界が小さくなっていることを認識し、姓に基本的なASCII /米国英語の文字のみが含まれる)とは想定できません)。または、フィールドの送信を停止する可能性があります。または、将来的に1つ以上のフィールドを追加することもできます。これと他のものの任意の組み合わせです。なぜVARCHAR
列のみに注目するのですか?現在INT
値を送信していて、年または2つは最大値に達し、BIGINT
の送信を開始しますか?値0〜5の「status」フィールドがある場合はどうでしょうか。増加を可能にするために「パディング」されているINT
を想定していますが、おそらくTINYINT
?
安全に予測できる唯一のことは、顧客データがどのように変化するかを予測しようとすることは、正しいというよりも間違っていることが多いということです。そして、正しいことは運/偶然の問題です(運がなければ、宝くじをプレイしてください;)。
したがって、ガイドラインは次のとおりです。
すでにサンプルデータがあります。ただし、お客様の連絡先情報(電話またはメール、あるいはその両方)もご確認ください。それらに連絡してください!お客様のデータ仕様を尋ねます(システムと同様に、現在システムにあるデータの最大長は35ですが、システムではVARCHAR(50)
として定義されており、システムはその長さまで受け入れます、その場合は50を使用する必要があります。また、変更の短期的な計画や、それらのデータ型(タイプやサイズ)があるかどうかを尋ねます。