Oracleデータベースのデータ構造
Oracleデータベースを考える時にデータ構造を知っておくと理解しやすい。
なお、ここではOracle 8以降の定義とその変更を扱うが、Oracle 8より古い製品については個人的に知識がないので割愛する。
以降、「Oracle データベース」は単に「Oracle」と表記する。
データブロック
OracleがディスクI/Oやキャッシュ管理を行うときの最小単位である。
物理的なディスク装置の方でRAIDなどを使ってディスクI/Oを分散させている場合は、このデータブロックの値と整合性を取らないと、パフォーマンス上よろしくない。
ブロックサイズとパフォーマンス
取り出したいレコードがデータブロックの中に1つしかなくても、ブロック1つ全体がディスクからキャッシュに読み込まれる。
一度に読み込むレコード件数が少なく、1つのブロックに含まれるレコードの比率が小さいと、不要なディスク読み込みとキャッシュヒット率の低下を招きパフォーマンスに悪影響を与える。
一方、全表検索を行う場合、1ブロックに含まれるレコード数が少ないと、読み込まなければならないブロック数が増えるため、パフォーマンスに悪影響を与える。
よって、最適なブロックサイズはデータベースの用途によって変わってくる。
データウェアハウスのように大量、かつ連続したデータの入出力を行うアプリケーションでは、大きめな値を設定する。
オンライントランザクション処理のようなランダムアクセスを主に行うアプリケーションでは、小さめな値を設定する。
レコードとデータブロックの関係
データベースの1つのテーブルの中の1行にあたるものをレコードという。
データブロックの中には複数のレコードが保存される。
VARCHAR2のような可変長のデータがある場合、Oracleは新規にレコードを作成した時点で必要な領域しか確保しない。その後のレコード更新でデータ量が増えた時点で領域を新たに確保する。
一つのレコードが大きくて、1つのデータブロックに収まらず、複数のブロックに渡って保存されることがある。これを行連鎖という。
データの更新により、一つのレコードのサイズが大きくなり、あふれたデータを他のデータブロックに保存することを、行移行という。
行連鎖、行移行ともにパフォーマンスの劣化を招く。
行連鎖の解決方法
テーブルを分割して、1レコードのサイズを小さくする。
データブロックのサイズを大きくする。
データブロックのPCT_FREEパラメータを小さくして、1データブロックに保存できるサイズを大きくする。
いずれの方法でも、既存のデータはエクスポート/インポートなどを行わないと、行連鎖は解決できない。
行移行の解決方法
頻繁に発生する場合はPCT_FREEパラメータを大きくして、レコードが更新されてデータ量が増えても同じブロックに収まる可能性を高める。
データのエクスポート/インポートなどを行うことで、行連鎖を解決する。
エクステント
連続したブロックの集合体がエクステントである。
レコード量が増加し、新たなディスク領域を確保する必要が生じた時に、Oracleではエクステント単位でデータの領域確保を行う。
物理的には、1つのエクステントは1つのデータファイルに属する。
論理的には、1つのエクステントは1つのセグメントにのみ属する。
セグメント
エクステントの集合体がセグメントである。
データベースを管理する際の論理的な単位である。
通常の1つのテーブルやインデックスが1セグメントにあたる。
物理的には、セグメントは複数のデータファイルに保存されることもある。
表領域
表領域は一時表領域やシステム表領域、ユーザー表領域など、データベースを管理する時の論理的な単位である。
物理的には1つ以上のデータファイルを含む。
論理的には複数のセグメントを含む。
データファイル
データファイルはOS上のファイルである。
データファイルは物理的なものであり、OS側で管理するべきものである。
Oracleのデータベース上の操作でデータファイルの保管場所を変更しても、OS上のファイルは移動せず、OSコマンドを用いて移動する必要がある。
論理的なバックアップであるインポート/エクスポートユーティリティでは、表単位、スキーマ単位といった論理的な単位で対象を指定できるが、物理的なバックアップではデータファイル単位が最小のバックアップ単位となる。