16

Oracleがの定義にsizeパラメータを必要とする理由を知りたいVARCHAR2

それは制約のためだと思います。オラクルがこのパラメータをdataTypeのようなオプションとして使用する方が良いオプションでしょNUMBERうか?

値が列のサイズ定義よりも大きい場合があるため、古いテーブルのサイズをより大きなサイズに変更する際に問題が発生することがよくありVARCHAR2ます。

VARCHAR2(10)または。のタイプを定義することも同じVARCHAR2(1000)です。

不必要な制約だと思います。そうでない場合は、この制約が何か有用な結果をもたらした実際のケースを知っていますか?そして、なぜそのような宣言がNUMBERタイプにないのですか?

4

6 に答える 6

24

varchar2(10) または varchar2(1000) のタイプを定義することは同じです。

いいえ、まったく同じではありません。

  1. 列の長さは、画面を作成する開発者にとって有用なメタデータです。
  2. 同様に、TOAD や SQL Developer などの自動クエリ ツールは、結果をレンダリングするときに列の長さを使用します。
  3. データベースは、PL/SQL コレクションにメモリを割り当てるときに変数の長さを使用します。そのメモリーが PGA のスーパーサイジングから取り出されると、サーバーのメモリーが不足するため、変数宣言によってプログラムが失敗する可能性があります。
  4. PL/SQL プログラムでの単一変数の宣言にも同様の問題がありますが、コレクションが問題を増大させる傾向があるだけです。
  5. 列が大きすぎると、複合インデックスの問題が生じます。以下は、8Kブロックのデータベースです

....

SQL> create table t23 (col1 varchar2(4000), col2 varchar2(4000))
  2  /

Table created.

SQL> create index t23_i on t23(col1,col2)
  2  /
create index t23_i on t23(col1,col2)
                      *
ERROR at line 1:
ORA-01450: maximum key length (6398) exceeded


SQL>

しかし何よりも、列のサイズはエラー チェックの形式です。列の長さが 10 文字であると想定されていて、オートノミック プロセスが 1000 文字をロードしようとしている場合は、何か問題があります。プロセスは失敗するはずなので、duff データをロードしている理由を調査できます。もう 1 つの方法は、ゴミだらけのデータベースです。それが必要な場合は、全員に Excel を渡して、それで処理を完了させるべきでした。

過小評価していることが判明したときに列のサイズを変更するのは面倒です。しかし、これは頻繁に発生するわけではなく、変数の長さをハードコーディングする代わりに、PL/SQL で %TYPE および SUBTYPE 宣言を使用することで、多くの問題を軽減できます。


「なぜNUMBER型にそのような宣言がないのですか」

数値が異なります。まず、数値の最大サイズは、同等のテキスト (38 桁の精度が保証されている) よりもはるかに小さいです。

ただし、重要な違いは、Oracle は数値を指数表記で格納するため、数値の算術サイズとそれが消費するストレージ スペースの間に単純な関係がないことです。

SQL> select vsize(123456789012345678901) n1
  2         , vsize(999999999999999999999999999999) n2
  3         , vsize(0.000000000000000000001) n3
  4         , vsize(1000000000000000000000000) n4
  5  from dual
  6  /

        N1         N2         N3         N4
---------- ---------- ---------- ----------
        12         16          2          2

SQL> 

それにもかかわらず、特に整数やお金を扱っている場合は、可能な限り位取りと精度を指定することをお勧めします。

于 2010-02-11T13:41:04.843 に答える
8

リレーショナル データベースが開発された歴史的背景を思い出すことは重要だと思います。それらが開発されていた当時 (70 年代後半から 80 年代前半) に一般的に利用できるコンピュータは、現在のものよりもはるかに小さく (メモリとディスク容量の点で)、(CPU の点で) 強力ではありませんでした。やむを得ない懸念。COBOL はビジネス コンピューティングの共通言語であり (現在も広く使用されています)、Smalltalk や C++ などのオブジェクト指向言語は実用的な目的では知られていませんでした。当時、プログラムは各データ要素に必要なストレージの量を正確に宣言することが期待されていました。たとえば、文字列の場合は 10 バイト、短整数の場合は 2 バイト、浮動小数点数の場合は 4 バイトなどです。そのため、このスタイルの宣言は、当時新しく開発されたリレーショナル データベースで使用されました。もっと端的に言えば、各データ要素が必要なストレージの量を (暗黙的または明示的に) 宣言するという仮定が立てられ、これが非常に基本的なレベルでリレーショナル エンジンにコード化されました。

現在、少なくともディスクへのデータの保存に関する限り、この要件は徐々に緩和されています。Oracle では、NUMBER データ型が柔軟にスペースを割り当て、その値を格納するために必要な最小限のスペースのみが実際に使用され、VARCHAR2 列は、末尾の空白を格納せずに実際のデータを格納するのに十分なディスク スペースのみを使用すると考えています。ただし、VARCHAR2 に必要なストレージの最大量を宣言する必要があります。

VARCHAR2 サブタイプを宣言する方法については、SYS.STANDARD パッケージを参照してください。たとえば、長さの仕様を追加せずに使用できる独自の「文字列」タイプが必要な場合は、次のようにします。

SUBTYPE MY_STRING IS VARCHAR2(4000);

ただし、問題の列にインデックスを付ける場合は、これに注意してください (以前に @APC が指摘したように)。

長さを宣言せずにSTRING(ところで、SYS.STANDARDでVARCHAR2のサブタイプとして定義されている)を宣言できるようにしたいということに同意しますが、それはOracleの仕組みではありません.私は自分自身のリレーショナル データベースを書き始めるつもりはありません (傾くための独自の風車があります。ありがとう :-) 現状に沿って進みます。

これが役立つことを願っています。

于 2010-02-11T14:11:23.597 に答える
5

すべてのデータベーステーブルのすべての列をCLOBにしないのはなぜですか?そうすれば、最大長を気にする必要はありません...

しかし、真剣に:

データ型の長さの制約は、他の制約と同じ理由で存在します。テーブルに正常に格納されたデータが定義した制約に準拠していることを確認することで、すべてのアプリケーションコードに散在する必要のあるエラーチェックの量を減らします。

于 2010-02-11T03:57:48.300 に答える
3

情報を抽出するという観点からは、フィールドの大きさを知ることは非常に役立ちます。たとえば、住所を封筒に印刷したり、画面に表示したりする必要がある場合、フィールドの大きさを知りたいと思うでしょう。

または、非常に大きな封筒を購入します。

于 2010-02-11T05:24:35.983 に答える
3

char フィールドのようにディスク上に設定されたバイト数を割り当てるわけではありませんが、サイジングには適切な理由があります。

  • データ リーダーのメモリ割り当て (最大行サイズに基づく)
  • 大きな列にインデックスを付けると、ブロック サイズが影響します
  • 等...

他の誰かが考えることができる理由は他にもあると確信していますが、それらは過去のプロジェクトで誰かがvarchar2(4000)すべてを選んだのを見たものです.

于 2010-02-11T00:15:33.580 に答える