web-dev-qa-db-ja.com

Oracle varchar2に定義パラメータとして必須のサイズがあるのはなぜですか?

Oracleが_VARCHAR2_の定義にサイズパラメータを必要とする理由を知りたい。

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

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

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

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

15
user2427

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文字を読み込もうとしている場合は、問題が発生しています。プロセスは失敗するはずなので、ダフデータをロードしている理由を調査できます。別の方法は、ゴミでいっぱいのデータベースです。それが必要な場合は、すべての人に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> 

それでも、特に整数、たとえば、またはお金を扱う場合は、可能な限りスケールと精度を指定することをお勧めします。

24
APC

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

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

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

SUBTYPE MY_STRING IS VARCHAR2(4000);

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

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

これがお役に立てば幸いです。

7
Bob Jarvis

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

しかし、真剣に:

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

5
Jeffrey Kemp

Charフィールドのようにディスクに設定されたバイト数を割り当てない場合でも、サイズ設定には適切な理由があります。

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

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

3
Nick Craver

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

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

3
Gary Myers

パフォーマンスに影響を与える可能性があります。MySQLでは、temporary tablesおよびMEMORY tablesは、VARCHAR列を固定長の列として格納し、最大長までパディングします。

必要な最大サイズよりもはるかに大きいVARCHAR列を設計すると、必要以上のメモリを消費します。これはcache efficiency, sorting speed, etcに影響します。

だからあなたはあなたの弦の下にある最大の長さを与えます。文字の最大長が10の場合のように、長さを100以上にしないでください。

0
Vipin Jain