20

TDWTF に関するやや白熱した議論の中で、DB 内の varchar 列のサイズに関する疑問が生じました。

たとえば、個人の名前 (名前のみで姓は含まれない) を含むフィールドを考えてみましょう。それほど長くないことは容易にわかります。ほとんどの人の名前は 10 文字未満であり、20 文字を超える人はほとんどいません。たとえば、varchar(50) という列を作成すると、これまでに遭遇したすべての名前が確実に保持されます。

ただし、ほとんどの DBMS では、varchar(50) を作成しても varchar(255) を作成しても、サイズや速度に違いはありません。

では、なぜ列をできるだけ小さくしようとするのでしょうか? 場合によっては、実際に文字列の長さに制限を設けたい場合があることは理解していますが、ほとんどの場合、そうではありません。そして、非常に長い名前を持つ人のまれなケースがある場合にのみ、より広いマージンが有益になります.


追加:人々は、「サイズや速度に違いはない」という声明への参照を求めています。わかった。どうぞ:

MSSQL の場合:http://msdn.microsoft.com/en-us/library/ms176089.aspx

ストレージサイズは、入力されたデータの実際の長さ + 2 バイトです。

MySQL の場合:http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html

列の値に 0 ~ 255 バイトが必要な場合は L + 1 バイト、値が 255 バイトを超える可能性がある場合は L + 2 バイト

Oracle のドキュメントが見つからず、他の DBMS を使用したことがありません。しかし、私はそれがそこで違うと信じる理由はありません。

4

9 に答える 9

23

I can only speak for Oracle. A VARCHAR2(50) and a VARCHAR2(255) take up exactly the same amount of space and perform identically, if you enter the value 'SMITH'.

However, the reason why it is generally not a good idea to go around declaring all your textual columns as VARCHAR2(4000) is that column length is, effectively, another constraint. And constraints are database implementation of business rules, so they are definitely something that should be defined on the database side of things.

As a for-example. You define a CHECK constraint on a column so that the values it can accept are only 'Y' and 'N'. That saves your application from having to deal with 'y' and 'n' or even '1' and '0'. The check constraint ensures your data conforms to expected standards. Your application code can then make valid assumptions about the nature of the data it has to deal with.

Column length definition is in the same boat. You declare something to be a VARCHAR2(10) because you don't want it accepting an entry of 'ABC123ZYX456' (for whatever reason!)

In Australia, I define STATE columns to be a varchar2(3) because I don't want people typing in 'New South Wales' or 'South Australia'. The column definition pretty much forces them to be entered as 'NSW' and 'SA'. In that sense, a VARCHAR2(3) is almost as much a check constraint as actually specifying a CHECK IN ('NSW','SA','VIC' etc) constraint.

In short, proper column lengths are a way of encoding business rules. They're another form of constraint. They bring all the advantages of constraints (and suffer from many of the same drawbacks). And they ensure, to a small extent, a degree of 'data cleanliness' that "proper" constraints help with, too.

I don't buy the argument, either, that it's best to stick these sorts of things in the client app because it's easier to change there. You have 20,000 people using an app, that's 20,000 updates. You have one database, that's one update. The 'easier to change the client app' argument, if true, would potentially mean the database just gets treated as a giant bit bucket with all the clever logic being handled in client code. It's a big discussion to have, but since all RDBMSes let you define constraints and so on in the database itself, it's pretty clear that there's at least a worthwhile case to be made that such fundamental logic belongs in the backend.

于 2009-08-14T01:05:07.200 に答える
5

参照が見つかりませんが、クエリオプティマイザがvarcharの長さを考慮していると聞きました。

varcharの長さを定義すると、意図を伝えるのに役立ちます。定義された制約が多いほど、データの信頼性は高くなります。

于 2009-08-11T16:58:53.497 に答える
3

重要な違いの 1 つは、任意に大きな制限を指定すること [eg VARCHAR(2000)] と、制限を必要としないデータ型を使用すること [eg VARCHAR(MAX)or TEXT] との違いです。

PostgreSQL はすべての固定長VARCHARs をその無制限の型に基づいており、値をページ外に格納するなど、値を格納する方法を値ごとTEXTに動的に決定します。この場合の長さ指定子は実際には単なる制約であり、その使用は実際にはお勧めできません。(参照)

他の DBMS では、「無制限」のページ外ストレージが必要かどうかをユーザーが選択する必要があり、通常は利便性やパフォーマンスに関連するコストが伴います。

またはを使用VARCHAR(<n>)する利点がある場合は、テーブルを設計するときにの値を選択する必要があります。テーブル行またはインデックス エントリの最大幅があると仮定すると、次の制約を適用する必要があります。VARCHAR(MAX)TEXT<n>

  1. <n>以下でなければなりません<max width>
  2. の場合<n> = <max width>、テーブル/インデックスは 1 列のみを持つことができます
  3. <x>一般に、テーブル/インデックスには、(平均で)次の列のみを含めることができます<n> = <max width> / <x>

したがって、 の値が制約としてのみ機能するわけではなく、 の選択は設計の一部でなければなりません。(DBMS に厳密な制限がない場合でも、幅を特定の制限内に維持するパフォーマンス上の理由がある場合があります。)<n><n>

上記のルールを使用して、予想されるテーブルのアーキテクチャに基づいて (将来の変更の影響を考慮して)の最大値を割り当てることができます。ただし、各列の予想されるデータに基づいての最小<n>を定義する方が理にかなっています。ほとんどの場合、最も近い「ラウンド数」に展開します。たとえば、 、 、 、または のいずれかを常に使用し、最適なものを使用します。<n>VARCHAR(10)VARCHAR(50)VARCHAR(200)VARCHAR(1000)

于 2009-08-17T19:12:14.800 に答える
3

では、なぜ列をできるだけ小さくしようとするのでしょうか? 私はそれらをできるだけ小さくすることを信じていませんが、適切なサイズにしています. (n)varchar を大きくするのではなく小さくするいくつかの理由:

1) より大きなフィールドでは、データベースを使用するすべてのクライアントがフル サイズを処理できる必要があります。たとえば、各フィールドに 255 文字の米国の住所を保持するシステムを考えてみましょう (あなたが参照している TDWTF に似ていると思います)。

  • ファーストネーム
  • 苗字
  • 住所1
  • 住所2
  • 郵便番号

データ入力画面では、フィールドごとに 255 文字を許可して表示する必要があります。難しいことではありませんが、大きなフィールドでは見栄えがよくありません 請求書の印刷では、大きなフィールドを処理するために改行ロジックが必要になります。ツールによっては、それほど難しくありません。

しかし、これらのフィールドのそれぞれに 255 文字、またはそれらのフィールドのいずれか 1 つに 255 文字の封筒の住所を書式設定するという問題は避けたいと思います。フィールドが長すぎて収まらない場合、切り捨てますか? 誰かが「House Number Streat Number ... blah blah blah ... Appartment number 111」の住所行 1 を持っている人は素晴らしいです。そして、重要なアパートの番号を削除します。ラッピングしますか?いくら?封筒の小さな箱に収まらない場合はどうしますか? 例外を発生させて、誰かに手書きで手紙を書いてもらいますか?

2) varchar(50) と varchar(255) に保持される 10 文字のデータはサイズや速度に影響しませんが、255 文字を許可すると、より多くのスペースを使用できます。そして、すべてのフィールドがそれほど大きい場合、SQL Server 2000 のサイズ制限に達する可能性があります (2005 年と 2008 年については、それらが 1 ページを超える行を処理できるかどうかを確認していません)。誰かが実際に使用可能なすべての文字を使用した場合、チェーンが発生します。

3) インデックスには、リーフ ページよりも厳しいサイズ制限があります。作成する varchar が大きすぎる場合は、インデックス、特に複合インデックスを除外できます。


一方で、私は自分のアドレスの 1 行目が長いので、完全な入力を許可しない Web サイトに不満を感じています。

于 2009-08-11T16:45:45.707 に答える
2

私の意見では、これに対する簡単な答えは、その列をインデックス キーとして使用できないという事実です。いずれにせよ、インデックスを適用したい場合はいつでも、「正しいサイズの」列は非常に理にかなっています。可変長列の更新は、所定の場所で行われず、ある程度の断片化が発生する可能性があるため、コストのかかる操作になる可能性があります。

MS SQ-Serverに関するすべて。

于 2009-08-18T19:17:52.893 に答える
1

ラベルを印刷する場合、通常は文字列を 35 文字以内にする必要があります。これが、ラベルの印刷に使用される行を受け入れるために使用する Varchar のサイズを制御する必要がある理由です。

于 2013-02-14T20:09:51.473 に答える
1

あなたの質問に答えます。varchar(50) と varchar(255) の間で DBMS に違いがない場合、なぜ DBMS で区別できるのでしょうか? DBMS が単純に「xxx 文字までは varchar を使用し、それ以上の文字には text/clob/etc. を使用する」と言わないのはなぜですか。確かに、おそらく Microsoft/Oracle/IBM は歴史的な理由から長さの定義を保持しているかもしれませんが、複数のストレージ バックエンドを持つ MySQL のような DBMS についてはどうでしょうか。なぜすべてが定義可能な文字列の長さを実装しているのでしょうか?

于 2009-08-12T17:35:46.550 に答える