ストレージ管理の単位はいま述べた8Kbytesの「ページ」だが、テーブルやインデックスなどのオブジェクトは、基本的にはページ単位ではなく、連続した8ページをひとまとめとした「エクステント(extent)」と呼ばれる単位で割り当てられる。1エクステントのサイズは64Kbytesである。例えば1Mbytesのデータなら、16個のエクステントが使用される(例外もあるが、これについてはすぐ次で述べる)。
上図では、図の構成上、一連のエクステントが物理的に連続しているように描かれているが、実際のエクステントは物理的に連続しているとは限らない。FATやNTFSなどのファイル・システムにおけるクラスタ(ファイルのデータを記録する最小単位)がそうであるように、物理的には不連続なエクステントを、論理的には連続したものとして扱うための機構が用意されている。
テーブルやインデックスのデータを新たに割り当てる場合、SQL Server 2000は空きエクステントを検索し、そこにデータを保存する。
基本的にテーブルやインデックスは、エクステントを単位に割り当てられるのだが、64Kbytesに満たない小さなテーブルが多数存在する場合、このルールを適用すると、効率的なデータ割り当てができない。そこでSQL Server 2000では、エクステントを2種類に分類し、小さなテーブルでも効率的にエクステントを使えるようにしている。
1つは「混合エクステント」と呼ばれるもので、こちらはエクステント内のページが、ページごとに異なるオブジェクトによって使用される。つまり複数のテーブルやインデックスによって、1つのエクステントが共有される場合がある。エクステント内には8個のページがあるので、最大8個のオブジェクトが1つのエクステントを共有できる。
エクステント1個のサイズ(64Kbytes)を超えるテーブルやインデックスでは、エクステント内の全ページを使ってそのオブジェクのデータが保存される。こちらは混合エクステントに対し、「単一エクステント」と呼ばれる。逆にいえば、単一エクステント内の各ページは、1つのオブジェクトによって使用されている。
これらの違いを図にすると次のようになる。
通常、新規にテーブル(またはインデックス)を作成したときには、最初に混合エクステントが割り当てられる。以後そのテーブル(インデックス)が拡張して8ページを超えるサイズになったら、単一エクステントに切り替えられる。
テーブルやインデックスなどのデータを素早く割り当てるために、SQL Server 2000はエクステントの空き領域管理を工夫している。このために利用される管理領域がGAM(Global Allocation Map)とSGAM(Shared Global Allocation Map)である(冒頭で紹介した「ページ・タイプの表」を参照)。
GAMとSGAMの内部には、エクステントごとに1bitが対応するビットマップがそれぞれ格納されている。1つのGAM/SGAMでは、6万4000個のエクステント(64Kbytes×64000=4Gbytes)を管理できる。GAM/SGAMのビットの組み合わせにより、そのビットに対応するエクステントの使用状態が表される。組み合わせとエクステントの使用状態は次のとおり。
GAMビット | SGAMビット | エクステントの使用状態 |
---|---|---|
1 | 0 | 空きで未使用のエクステント |
0 | 0 | 単一エクステント、またはフルの(すべてのページが使われている)混合エクステント |
0 | 1 | 空きページがある混合エクステント |
GAM/SGAMビットとエクステントの使用状態 |
これらの関係を図にすると次のようになる。
実際の処理はより複雑だが、GAM/SGAMを使ったSQL Server 2000による空きエクステント管理の基本的なアルゴリズムをまとめると次ようになる。
空き領域に対する処理 | GAM/SGAMに対する処理 |
---|---|
単一エクステントの割り当て | GAMの中から1のビットを探す。このビットに対応するエクステントを割り当て、ビットを0にする |
空きのある混合エクステントの検索 | SGAMの中から1のビットを探す |
混合エクステントの新規割り当て | GAMビットが1のエクステントを検索し、ビットを0にする。そのエクステントに対応するSGAMのビットを1にする |
エクステントの解放 | 対応するGAMビットを1に、SGAMのビットを0にする |
空きエクステント処理のアルゴリズムとGAM/SGAMの処理 |
すでに述べたとおり、テキスト(text型/ntext型)やイメージ(image型)のデータは、最大で2Gbytesに及ぶことがあるため、データ行の内部に格納できない場合がある。小さいものはデータ行に直接格納可能だが、大きすぎてそれができない場合、SQL Server 2000はデータを別のページに割り当て、それらをBツリー構造を使って高速に取り出すためのルート構造へのテキスト・ポインタをデータ行に挿入する。
この図は、1Kbytesのテキスト/イメージ・データを書き込んだ後、10Kbytesのデータを書き込んだところである。最初の書き込みであるページがブロック1として割り当てられ、1Kbytesのデータが格納される。2回目の書き込みでは、まずブロック1の残りの7Kbytesが使われ、残る3Kbytesのデータがブロック2に書き込まれる。
今回はSQL Server 2000データベースの物理アーキテクチャについて述べた。このようにSQL Server 2000で作成されるデータベースは、最終的にはWindows OS上の物理的なファイルとして保存されるものの、その内部では、ページとエクステントというSQL Server 2000独自の管理方法が適用されており、これらによって高速にデータの書き込みや検索を行えるようにしている。
一般的なデータベースの設計やアプリケーション開発では、こうしたデータベースの物理アーキテクチャに踏み込む必要に迫られることはあまりないだろう。しかしSQL Server 2000の挙動を理解して応用に役立てるための一助になるはずだ。
引き続き次回は、SQL Server 2000デーベースの論理アーキテクチャについて説明する予定である。
Copyright© Digital Advantage Corp. All Rights Reserved.