MicroKernel エンジンの基礎
以下のトピックでは、MicroKernel エンジンの機能について説明します。
MicroKernel エンジンの概要
Btrieve API は、MicroKernel エンジンの低レベル インターフェイスで、データベース設計の機能面を具現するものですが、SQL、Java、ODBC などの高レベル インターフェイスには透過的です。たとえば、SQL インターフェイスはデータが物理的にどのように格納されるかに関係なく動作します。しかし、MicroKernel エンジンの開発者はページ サイズ、物理および論理カレンシー、型検査、妥当性検査などの低レベルの側面を考慮する必要があります。これらの低レベルの側面を考慮しても、Btrieve API には優れた柔軟性とデータに対する制御性があります。
MicroKernel エンジンは情報をファイルに格納します。このファイルのサイズは、13.0 バージョンのファイル形式ではテラバイトまでです(9.5 バージョンでは 256 GB、9.x より前のバージョンでは 128 GB、それ以前のバージョンでは 64 GB です)。各データ ファイル内には、データ バイトを収容するレコードがあります。1 つのファイルに数十億個のレコードを収容できます。
レコード内のデータは、社員の名前、ID、住所、電話番号、賃率などを表します。しかし、MicroKernel エンジンはレコードを単なるバイトの集合として解釈します。つまり、レコード内で論理的に区別されている情報を認識しません。MicroKernel エンジンにおいては、ラスト ネーム、ファースト ネーム、社員 ID などはレコード内に存在しません。
MicroKernel エンジンがレコード内で認識できる唯一の区別されている情報の部分は、キーです。キーは、レコードに対する高速な直接アクセスと、キー値によるレコードのソート手段を提供します。MicroKernel エンジンには各ファイル内のレコードの構造を理解する方法がないため、以下の項目を識別することによって各キーを定義します。
•番号。これは、キーのリスト内のキーの順序です。バージョン 6.0 以降のファイルでは、キー番号間にギャップをとることができます。つまり、MicroKernel エンジンは連続番号の付いたキーを必要としません。キーを追加する場合、キー番号を指定したり、MicroKernel エンジンに使用可能な最小キー番号を割り当てさせることができます。キーを削除する場合、残りのキー番号をそのままにしたり、MicroKernel エンジンに連続番号を付け直させることができます。
•位置。これは、キーのレコードの先頭からのオフセット(バイト単位)です。
•長さ。これは、キーに使用するバイト数です。
•型。これは、キーのデータ型です。
•属性。これは、MicroKernel エンジンにキー値を処理させる方法に関する追加情報を示します。MicroKernel エンジンは、セグメント、重複可能、変更可能、ソート順、大文字と小文字の区別、オルタネート コレーティング シーケンス、ヌル値などのキー属性をサポートします。
キーはいつでも作成または削除することができます。MicroKernel エンジンは、データ ファイルで定義されたキーごとにインデックスを作成します。インデックスは、データ ファイル自体の内部に格納されます。インデックスは、ファイル内の各キー値を実際のデータ内のオフセットへマップします。通常は、MicroKernel エンジンがデータのアクセスまたはソートを行う場合、ファイル内のすべてのレコードを検索しません。その代わり、インデックスを検索し、その後要求に合うレコードだけを処理します。
インデックスは、データ ファイルの作成時、またはそれ以降いつでも作成できます。データ ファイルを作成するときは、MicroKernel エンジンがインデックスの作成に使用するキーを 1 つまたは複数定義できます。
ファイルを作成した後に、外部インデックスを定義することもできます。外部インデックス ファイルは、指定するキーでソートされたレコードを含む標準データ ファイルです。各レコードは、以下の項目から成ります。
•元のデータ ファイルにおけるレコードの物理位置を識別するアドレス
•キー値
いつインデックスを作成するかに関係なく、ポジショニングの規則(どのレコードが現在のレコードで、どのレコードが次レコードかなどを管理するガイドライン)は同じです。
ファイルを作成すると同時にインデックスを作成する場合、MicroKernel エンジンはレコードがファイルに挿入された年代順に重複キー値を格納します。既に存在するファイルのインデックスを作成する場合、MicroKernel エンジンは、インデックス作成時の対応するレコードの物理順で重複キー値を格納します。MicroKernel エンジンがインデックスに重複キー値を格納する方法は、キーがリンク重複か繰り返し重複かによっても異なります。詳細については、
重複可能性を参照してください。
メモ:レコードの年代順は、レコードを更新してそのキー値を変更する場合、インデックスを削除して作成し直す場合、またはファイルを作成し直す場合に変化する可能性があります。したがって、ファイル内のレコードの順序がレコードの挿入された順序を常に反映するとは考えないでください。レコード挿入順序をトラッキングする場合は、AUTOINCREMENT 型のキーを使用してください。
アプリケーションでインデックスが不要になれば、インデックスを削除できます。データ ページやその他のインデックス ページに対して、インデックスがファイル内で使用した領域が解放されます。(ただし、この空き領域はファイルに割り当てられたままになります。インデックスを削除した後に物理的なファイル サイズは減少しません。)
キーの定義に関する具体的な情報については、
データベースの設計を参照してください。
MicroKernel エンジン環境
エンド ユーザーが MicroKernel エンジン アプリケーションを実行する前に、エンド ユーザーのコンピューターで MicroKernel エンジンのバージョンを使用できるようにする必要があります。アプリケーションに不可欠な MicroKernel エンジン ソフトウェア バージョンと環境設定に関する情報をエンド ユーザーに提供する必要があります。
設定に関する注記
エンド ユーザーは、MicroKernel エンジン アプリケーションについて以下の情報を知っておく必要があります。この情報を MicroKernel エンジン アプリケーションに添付するドキュメントに記載してください。
•アプリケーションに必要なメモリ容量。
アプリケーションには、MicroKernel エンジン自体で必要な容量より多いメモリまたはディスク領域が必要となる場合があります。アプリケーションのディスク領域とメモリ必要量を確定し、この情報をユーザーに伝えてください。MicroKernel エンジンのシステム要件については、『Getting Started with Zen』および弊社 Web サイトを参照してください。
•アプリケーションにデフォルト以外の MicroKernel エンジン構成の設定が必要かどうか。特に、エンド ユーザーがこれらの MicroKernel エンジン オプションを変更する必要があるかどうかを考慮してください。
•作成ファイルのバージョン。アプリケーションには MicroKernel エンジンの旧バージョンとの後方互換性が必要ですか?そうであれば、このオプションに対応する値を設定するようにエンド ユーザーに指示してください。
•インデックス バランス。アプリケーションは、作成するすべてのファイルにインデックス バランス ファイル属性を設定しますか?そうであれば、エンド ユーザーはインデックス バランスをデフォルトのオフにして使用できます。そうでなければ、MicroKernel レベルでインデックス バランスをオンにするようにエンド ユーザーに指示する必要があります。詳細については、
インデックス バランスを参照してください。
•システム データ。データベース内のすべてのファイルは重複のないキーを持っていますか?そうであれば、これらのファイルはトランザクション一貫性保持の機能を利用できます。そうでなければ、エンド ユーザーはファイルをトランザクション一貫保持性のあるものにするために[システム データの作成]を[必要な場合]または[常時]に設定しなければならない場合があります。
設定オプションの説明については、『Advanced Operations Guide』を参照してください。
ページ
ここでは、ページと MicroKernel エンジンによるページの処理方法に関する以下の情報を示します。
ページ タイプ
ファイルは、一連のページから構成されています。ページとは、データベースがメモリとディスクの間で転送する記憶容量の単位です。ファイルは、以下のページ タイプから構成されています。
ファイル コントロール レコード(FCR) | ファイルのファイル サイズ、ページ サイズ、その他の特性などのファイルに関する情報が含まれています。6.0 以降のすべてのデータ ファイル内の最初の 2 つのページは FCR ページです。MicroKernel エンジンは常に、FCR ページのうちの 1 ページを現在のページと見なします。現在の FCR ページには、最新のファイル情報が含まれています。 |
ページ アロケーション テーブル(PAT) | ファイル内のページを追跡するために使用される、MicroKernel エンジンの内部的な実装の一部。 |
データ | レコードの固定長部分が含まれています。MicroKernel エンジンは、1 つの固定長レコードを 2 つのデータ ページにまたがって分割しません。ファイルが可変長レコードを許可していないか、データ圧縮を使用しない場合、ファイルにはデータ ページはありますが可変ページはありません。 |
可変 | レコードの可変長部分が含まれています。レコードの可変長部分が可変ページの残りの領域より長い場合、MicroKernel エンジンは複数の可変ページにわたって可変長部分を分割します。ファイルが可変長レコードを許可しているか、データ圧縮を使用する場合、ファイルにはデータ ページと可変ページの両方があります。 |
インデックス | レコードの取得で使用されるキー値が含まれています。 |
オルタネート コレーティング シーケンス(ACS) | ファイル内のキーのオルタネート コレーティング シーケンスが含まれています。 |
6.0 以降のすべてのファイルには、FCR ページと PAT ページがあります。
標準ファイルにはデータ ページとインデックス ページも含まれており、オプションとして可変ページと ACS ページが含まれています。
データオンリー ファイルにはインデックス ページが含まれていません。
キーオンリー ファイルにはデータ ページが含まれていません。
ページ サイズ
ファイルを作成するときに固定ページ サイズを指定します。指定できるページ サイズやファイル オーバー ヘッドなどは、ファイル形式をはじめさまざまな要因によって異なります。ページ サイズの説明については、第
5 章
データベースの設計を参照してください。以下のセクションでは概要について説明します。
ページ サイズの基準
指定するページ サイズは、以下の基準を満たす必要があります。
•ファイルのレコード長に相応なデータ ページを使用可能にする。
各データ ページには、一定のバイト数のオーバーヘッド情報が含まれています。表
15 を参照してください。その後、MicroKernel エンジンは各データ ページにできるだけ多くのレコードを格納しますが、ページにまたがってレコードの固定長部分を分割することはありません。
最適なページ サイズでは、各データ ページの残余スペース量をできるだけ少なくしながら、最も多いレコードを収容できます。ページ サイズが大きいほど、通常はディスク領域の使用効率が高くなります。内部レコード長(ユーザー データ + レコード オーバーヘッド)が小さく、ページ サイズが大きいと、無駄な領域がかなりの量になる可能性があります。
•ファイルのキー定義に適合するインデックス ページを許可する。
各インデックス ページには、一定のバイト数のオーバーヘッド情報が含まれています。表
15 を参照してください。その後、ファイルのインデックス ページは 8 個のキーと各キーのオーバーヘッド情報を収容できる大きさがなければなりません(設定ごとのオーバーヘッドのバイト数の説明については、表
13、
14、
15、
16 および
17 を参照してください)。
•ファイルが必要とするキー セグメント数を許可する。
セグメント化で説明したように、ファイルに対して定義するページ サイズはそのファイルに対して指定できるキー セグメント数を制限します。
•パフォーマンスを最適化する。
パフォーマンスを最適化するには、ページ サイズを 2 のべき乗のサイズ、つまり、512 バイト、1024 バイト、2048 バイト、4096 バイト、8192 バイト、16384 バイトに設定します。MicroKernel エンジンの内部キャッシュは一度に複数のサイズのページを格納できますが、2 のべき乗単位に分割されます。ページ サイズ 1536、2560、3072、および 3584 では、実際に、MicroKernel エンジン キャッシュ内のメモリが無駄になります。2 のべき乗のページ サイズを使用すると、キャッシュの使用効率が良くなります。
大きなページ サイズと小さなページ サイズ
現代のオペレーティング システムを最も効率よく使用するには、より大きなページ サイズを選択する必要があります。DOS が傑出したオペレーティング システムであった時代、つまり、セクターが 512 バイトで、すべての I/O が 512 の倍数で発生していたときは、小さなページ サイズが使用されていました。現在はそうではありません。32 ビットおよび 64 ビットのオペレーティング システムでは、いずれもデータを 4096 バイトあるいはそれ以上のブロック単位でキャッシュに移動させます。CD ROM ドライブは、2048 バイト単位で読み取られます。
MicroKernel エンジンのインデックスは、4096 バイトあるいはそれ以上のページ サイズを使用する場合に最も効率が良くなります。キーはノードごとにさらに多くの分岐を持つため、正しいレコード アドレスを検索するための読み取りは少なくて済みます。このことは、アプリケーションがキーでランダムな読み取りを行っている場合に重要です。アプリケーションがキーまたはレコードでファイルに順次アクセスする場合は重要ではありません。
ページを小さくするもっともな理由は、競合を避けるためです。各ページのレコード数が少ないほど、さまざまなエンジンまたはトランザクションが同時に同じページを要求する可能性は低くなります。ファイルのレコード数が比較的少なく、レコードが小さい場合は、小さなページ サイズを選択できます。ファイルが大きいほど、競合の発生する可能性が低くなるようです。
大きなページ サイズのもう 1 つの潜在的な問題は、バージョン 7.0 以降のファイルに特有なものです。同じデータ ページに収容できるレコードまたは可変長セクションの数は最大 256 個です。短いレコード、圧縮されたレコード、または短い可変長セクションがある場合は、すべてのページにまだ数百バイト残っていても、すぐに制限に達する可能性があります。その結果、必要とされるよりもはるかに大きなファイルになります。レコード サイズを知ることで、このことがどの程度大きな問題かを計算できます。
ページ サイズの決定時に考慮する要素
•キーはページ サイズが大きいほど効率よく働きます。B ツリーのノードごとにより多くの分岐ができるため、B ツリーのレベルが少なくなります。レベルが少ないとは、ディスクの読み込みや書き込みが少ないことです。ディスク読み込みが少ないと、パフォーマンスは向上します。
•並行処理は、クライアント トランザクションが使用されている場合は特に、より小さなページの方が効率が良くなります。トランザクション時、MicroKernel エンジンは変更されるページをロックするので、ほかのすべてのクライアントは、トランザクションが終了または中止するまで、ロックされたページが解除されるのを待つ必要があります。たくさんのクライアントが並行して同一ページにアクセスを試みる場合、各ページで見つけられるデータが少ないほど効率が良くなります。
•ページへのランダム アクセスは、より小さなサイズのページの方が効率が良くなります。これは、実際に使用するデータがキャッシュにあることが多いためです。再度データにアクセスした場合、十中八九まだキャッシュ内にあるでしょう。
•大量のレコードにシーケンシャル アクセスする場合は、大きなサイズのページの方が一度により多くのレコードを読み取れるため、効率が良くなります。ページを読み取るたびにほとんどすべてを使用するので、確実に読み取り回数が少なくなります。
データベース設計者はこれらの相反するニーズの中から選択しなければなりません。参照テーブルはめったに変更されませんが、ほとんど常に検索またはスキャンされるため、大きなページ サイズにする必要があります。トランザクション内で頻繁に追加および更新されるトランザクション ファイルは、小さいページ サイズにする必要があります。
すべての要因を慎重に検討することによって、どのようなページ サイズにするのかに対する正しい答えを導くことができます。ページ サイズの選択の詳細については、
ページ サイズの選択を参照してください。
ファイル タイプ
Btrieve API は、3 つのデータ ファイル タイプ、大きなサイズのファイル、および長いファイル名をサポートしています。サポートされる最大ファイル サイズは、13.0 バージョンのファイル形式ではテラバイト、9.5 バージョンでは 256 GB、9.x より前のバージョンでは 128 GB、それ以前のバージョンでは 64 GB です。以下のトピックでは、これらの機能について説明します。
メモ:Btrieve 6.x およびそれ以前のユーザーのために、MicroKernel エンジンはファイルを 8.x および 7.x 形式で作成することができます。これらの新しい形式により、拡張性と新機能がもたらされました。
Btrieve 6.x およびそれ以前のバージョンは、7.0 以降のバージョンのファイルを開けません。しかし、6.x より後の Btrieve リリースでは、7.0 より前のファイルを開くことができます。このようなファイルを開くとき、ファイルをそのバージョンより後のファイル形式に変換しません。また、7.x または 6.x 形式のファイルを新しく作成する必要がある場合は、これらの形式でファイルを作成するように MicroKernel エンジンのファイル互換性を設定することもできます。
標準データ ファイル
標準 7.x 以降のファイルには、FCR の 2 ページに続けて多数の PAT ページ、インデックス ページ、データ ページがあり、ファイルによっては可変ページや ACS ページもあります。固定長レコードまたは可変長レコードで使用する標準ファイルを作成できます。標準ファイルにはすべてのインデックス構造とデータ レコードが含まれているので、MicroKernel エンジンはファイル内のレコードに関するすべてのインデックス情報を動的に保持できます。
データオンリー ファイル
データオンリー ファイルを作成する場合には、キー情報を何も指定しないので、Zen はファイルのインデックス ページを割り当てません。このため、初期のファイル サイズは標準ファイルの場合より小さくなります。データオンリー ファイルを作成後、ファイルにキーを追加できます。
キーオンリー ファイル
キーオンリー ファイルには、FCR ページに続けて多数の PAT ページとインデックス ページだけが含まれています。また、ファイルに参照整合性制約を定義した場合は、1 ページ以上の可変ページが含まれます。
キーオンリー ファイルはキーを 1 つだけ含み、レコード全体がそのキーと共に格納されるため、データ ページは不要です。キーオンリー ファイルは、レコードに単一のキーが含まれており、かつそのキーが各レコードの大部分を占有している場合に有効です。キーオンリー ファイルのもう 1 つの一般的な用途は、標準データ ファイルの外部インデックスとして使用する場合です。
キーオンリー ファイルには以下の制限が適用されます。
•各ファイルには 1 つのキーしか含められません。
•定義できる最大レコード長は 253 バイト(バージョン 6.0 より前は 255 バイト)です。
•キーオンリー ファイルではデータ圧縮を行えません。
ラージ ファイル
MicroKernel エンジンがサポートするファイル サイズは、13.0 バージョンのファイル形式ではテラバイトまで、9.5 バージョンでは 256 GB、9.x より前のバージョンでは 128 GB、それ以前のバージョンでは 64 GB です。ただし、多くのオペレーティング システムでは、単一のファイルでこれだけの大きなサイズをサポートしていません。オペレーティング システムのファイル サイズの制限より大きいファイルをサポートするために、MicroKernel エンジンは大きなファイルをオペレーティング システムでサポートできるさらに小さなファイルに分割します。大きな論理ファイルは、拡張ファイルと呼びます。拡張ファイルを構成するさらに小さい物理ファイルは、エクステンション ファイルと呼びます。ベース ファイルは、大きすぎて 1 つの物理ファイルとしてサポートできなくなった元のデータ ファイルです。非拡張(非セグメント化)ファイルは、より効率的な I/O を提供するので、パフォーマンスが向上します。
9.x 以降の形式のファイルが自動的に 2 GB ごとに
拡張されないようにすることができます。セグメント操作の設定を変更するには、『
Advanced Operations Guide』の
ZenCC での設定に記述されているように、Zen Control Center(ZenCC)の設定プロパティにアクセスします。ここで[
セグメント サイズを 2 GB に制限]オプションを設定することができます。この設定は、13.0 形式のファイルには影響しません。この形式はセグメント化されません。
このオプションが選択されていない場合、PSQL 9.x 以降のファイルが自動的に 2 GB にセグメント化されることはありません。バージョン 8.x およびそれ以前のデータ ファイルは、引き続き 2 GB に到達するごとに拡張されます。ファイルが既に拡張されている場合は、セグメント化されたままです。
設定プロパティに関わらず、すべてのファイルは現在のオペレーティング システムのファイル サイズ制限に基づいて引き続き拡張されます。
拡張ファイルなどのファイルのバックアップについては、
ファイルのバックアップを参照してください。
長いファイル名
MicroKernel エンジンは 255 バイト以下の長いファイル名をサポートします。以下の項目もこの上限に従います。
•ローカライズされたマルチバイトまたはシングル バイト バージョンの文字列。
•リクエスターによって作成された UTF-8 UNICODE 形式の UNC バージョンのファイル名。
[スペースを含むファイル/ディレクトリ名]クライアント設定オプションが無効になっていない限り、ファイル名にはスペースを含めることができます。デフォルト設定は、
オンです。『
Advanced Operations Guide』の
長いファイル名と埋め込みスペースのサポートを参照してください。
ラージ ファイルを使用する場合やアーカイブ ロギングまたは Continuous オペレーションの実行中など、MicroKernel エンジンが既存のファイル名に基づいて新しいファイルを作成する場合(『
Advanced Operations Guide』の
ログ、バックアップおよび復元を参照)は、以下の例に示すように、新しいファイル名には元のファイル名のできるだけ多くの部分を含み、特有のファイル拡張子を使用します。
元のファイル名 | Coutinuous オペレーションで作成されたファイル名 |
---|
LONG-NAME-WITHOUT-ANY-DOTS | LONG-NAME-WITHOUT-ANY-DOTS.^^^ |
VERYLONGNAME.DOT.DOT.MKD | VERYLONGNAME.DOT.DOT.^^^ |
データ型
7.x 以降のファイル形式を使用する場合、キーを定義する際には以下のデータ型を使用できます。
AUTOINCREMENT | BFLOAT | CURRENCY |
DATE | DECIMAL | FLOAT |
INTEGER | LSTRING | MONEY |
NUMERIC | NUMERICSA | NUMERICSTS |
TIME | TIMESTAMP | UNSIGNED BINARY |
ZSTRING | WSTRING | WZSTRING |
NULL INDICATOR | | |
6.x ファイル形式を使用している場合は、上記のうち CURRENCY、TIMESTAMP、および WZSTRING を除くすべてのデータ型を使用してキーを定義できます。
6.x より前のファイル形式を使用している場合、NUMERICSA および NUMERICSTS はデータ型やキー タイプとして使用できません。
詳細については、『
SQL Engine Reference』の
データ型を参照してください。
キー属性
以下のセクションでは、キーを定義するときに指定できる属性について説明します。
キー属性の解説
以下のトピックでは、キーに割り当てることができる属性について説明します。
セグメント化
キーは、各レコード内の 1 つ以上のセグメントから構成できます。レコード内の任意の連続バイトをセグメントとすることができます。キー タイプとソート順序は、キー内のセグメントごとに変えることができます。
使用できるインデックス セグメントの数はファイルのページ サイズによって異なります。
ページ サイズ(バイト数) | キー セグメントの最大数(ファイル バージョン別) |
---|
8.x 以前 | 9.0 | 9.5 | 13.0 |
---|
512 | 8 | 8 | 切り上げ2 | 切り上げ2 |
1024 | 23 | 23 | 97 | 切り上げ2 |
1536 | 24 | 24 | 切り上げ2 | 切り上げ2 |
2048 | 54 | 54 | 97 | 切り上げ2 |
2560 | 54 | 54 | 切り上げ2 | 切り上げ2 |
3072 | 54 | 54 | 切り上げ2 | 切り上げ2 |
3584 | 54 | 54 | 切り上げ2 | 切り上げ2 |
4096 | 119 | 119 | 2043 | 1833 |
8192 | N/A1 | 119 | 4203 | 3783 |
16384 | N/A1 | N/A1 | 4203 | 3783 |
1 N/A は「適用外」を意味します。 2 「切り上げ」は、ページ サイズを、ファイル バージョンでサポートされる次のサイズへ切り上げることを意味します。たとえば、512 は 1024 に切り上げられ、2560 は 4096 に切り上げるということです。 3 9.5 以降の形式のファイルでは 119 以上のセグメントを指定できますが、インデックスの数は 119 に制限されます。 |
インデックス セグメントと MicroKernel エンジンに関する詳細については、ステータス コード
26:指定されたキーの数が不正です。および
29:キー長が不正です。を参照してください。
キーの合計長はキー セグメントの長さの合計であり、最大長は 255 バイトです。レコード内でキー セグメントは互いに重なり合っていてもかまいません。
セグメント化されたキーが重複不能キーである場合、セグメントを組み合わせて一意の値をつくる必要がありますが、個々のセグメントには重複を含めることができます。このタイプのセグメント化されたキーを定義する場合、たとえ特定セグメントに重複がある可能性があっても、各セグメントにはキー レベル属性として duplicates=no を持ちます。特定セグメントが常に一意であるようにするには、セグメント化されたキー定義の他に個別の重複不能キーとしてそのセグメントを定義します。
MicroKernel エンジン呼び出しを行う場合、キー バッファーの形式はキー番号で指定されるキーを収容できなければなりません。したがって、keynumber=0 を定義した場合、キー 0 が 4 バイト整数ならば、キー バッファー パラメーターは以下のいずれかにすることができます。
•4 バイト整数へのポインター
•最初の要素または唯一の要素が 4 バイト整数である構造体へのポインター
•4 バイト以上の文字列またはバイト配列へのポインター
基本的には、MicroKernel エンジンはキー バッファーとして使用されるメモリの場所へのポインターを取得します。MicroKernel エンジンはそのメモリの場所に、Get Equal などのオペレーションで指定されたキー番号に対応するデータ値があることを期待します。また、MicroKernel エンジンはその場所にデータを書き込むことができ、書き込んだデータが指定されたキー番号に対応するキー値になります。このような場合は、キー値全体を収容できる十分なメモリの場所を割り当てる必要があります。
MicroKernel エンジンにとって、キーは、たとえ複数のセグメントから構成されていても、単一のデータの集合です。セグメント機能を使用すれば、連続していないデータのバイトを 1 つのキーとして結合できます。また、キー データの個々の部分に異なるソート規則(サポートされるデータ型で指定されているとおり)を適用できます。一般的に、1 つのキー セグメントに関連付けられているデータ型がソート規則として使用されます。ソート規則は、2 つの値を比較してどちらの値が大きいか決定する方法を MicroKernel エンジンに指示します。データ型は、データの妥当性検査に使用されません。
MicroKernel エンジンは、常にキー セグメントでなくキー全体を処理します。キーを処理するには、キー全体を保持できる十分な大きさのキー バッファーを設定します。アプリケーションの中には、すべての MicroKernel エンジン呼び出しで使用する汎用の 255 バイトのバッファーを定義しているものがあります。キーの最大サイズは 255 バイトですから、十分なサイズです。このキー バッファーにデータが返されたら、アプリケーションでは通常、キー セグメントと同じ型として宣言されているアプリケーションの変数または構造体に汎用バッファーのデータをコピーします。別の方法として、キーに直接対応するキー バッファー パラメーター(単純変数または構造体変数)を渡します。
たとえば、レコードを読み取りたいが、キーのすべてのセグメントでなく最初のセグメントの値しかわからないものとします。それでも、そのキーを使用してデータを検索することができます。ただし、すべてのセグメントに対応するキー バッファー全体を渡す必要があります。キー値の一部しかわからないので、Get Equal 呼び出しを使用できません。Get Greater Or Equal 呼び出しを使用する必要があります。この場合、わかっているだけのキー値でキー バッファーを初期化し、次に不明のキー セグメントに低い値またはヌル値を指定します。
たとえば、データ値 ulElement2、ulElement3、ulElement5 に相当する 3 つのセグメントから成る、キー 1 の定義があるとします。ulElement2 に必要な値がわかっている場合、キー バッファーを次のように初期化します。
SampleKey1.ulElement2 = <検索する値>;
SampleKey1.ulElement3 = 0;
SampleKey1.ulElement5 = 0;
次に、Get Greater Or Equal 呼び出しでキー バッファー パラメーターとして &SampleKey1 を渡します。MicroKernel エンジンが呼び出しを終了し、レコードが見つかった場合には、ステータス コード 0 が返され、対応するデータ レコードが返されて、キー バッファーに 3 つのセグメントすべてを含むキー値が設定されます。
重複可能性
Zen は重複キー値を処理する方法として、リンク(デフォルト)および繰り返しの 2 つをサポートします。リンク重複キーでは、MicroKernel エンジンはインデックス ページの 1 組のポインターを使用して、同じキー値を持つレコードのうち年代順に最初と最後のレコードを識別します。さらに、MicroKernel エンジンはデータ ページの各レコード内の 1 組のポインターを使用して、同じキー値を持つレコードのうち年代順に前のレコードと次のレコードを識別します。キー値は、インデックス ページにのみ 1 回格納されます。
繰り返し重複キーでは、MicroKernel エンジンはインデックス ページの 1 つのポインターを使用して、データ ページの対応するレコードを識別します。キー値は、インデックス ページとデータ ページの両方に格納されます。重複キーの詳細については、
重複キーを参照してください。
変更可能性
キーを変更可能キーとして定義すると、MicroKernel エンジンはレコードが挿入された後でもキーの値を変更できるようにします。キーの 1 つのセグメントが変更可能であれば、すべてのセグメントが変更可能でなければなりません。
ソート順序
デフォルトでは、MicroKernel エンジンはキー値を昇順(最小の値から最大の値へ)にソートします。しかし、MicroKernel エンジンがキー値を降順(最大の値から最小の値へ)に並べるように指定することができます。
メモ:MicroKernel エンジンの Get オペレーション(Get Greater(8)、Get Greater or Equal(9)、Get Less Than(10)および Get Less Than or Equal(11))で降順キーを使用するときは注意してください。この場合、Greater または Less はキーに関する順序を参照するため、降順キーの場合には、この順序は対応する昇順キーの逆になります。
降順キーで Get Greater(8)オペレーションを実行する場合、MicroKernel エンジンはキー バッファーで指定するキー値より小さい最初のキー値に対応するレコードを返します。たとえば、10 件のレコードと整数型の降順キーを持つファイルについて考えてみましょう。10 件のレコードの降順キーに格納されている実際の値は、整数 0、1、2、3、4、5、6、7、8、9 です。現在のレコードのキー値が 5 で Get Greater オペレーションを実行した場合、MicroKernel エンジンはキー値 4 を含むレコードを返します。
同様に、降順キーで Get Less Than(10)オペレーションを実行した場合、MicroKernel エンジンはキー バッファーで指定するキー値より次に大きい値を持つレコードを返します。前の例で、現在のレコードの降順キーの値が 5 で Get Less Than オペレーションを実行した場合、MicroKernel エンジンはキー値 6 を含むレコードを返します。
大文字と小文字の区別
デフォルトでは、MicroKernel エンジンは文字列キーをソートするときに大文字と小文字を区別します。つまり、小文字の前に大文字をソートします。キーを大文字小文字無視と定義すると、MicroKernel エンジンは大文字と小文字を区別せずに値をソートします。キーにオルタネート コレーティング シーケンス(ACS)がある場合、大文字と小文字の区別は適用されません。
ヌル値
Zen には、列のデータをヌル値として識別する方法が 2 つあります。ヌル値の元のタイプ(レガシー ヌルと呼びます)は、MicroKernel エンジンで長年使用されてきました。新しいタイプのヌル識別は、真のヌルと呼びます。このトピックでは、レガシー ヌルについて説明した後、MicroKernel エンジンでの真のヌルの使用について詳細に説明します。
レガシー ヌル
ヌル値を許可するフィールドを定義する元の方法は「擬似ヌル」または「レガシー ヌル」と呼びます。これは、フィールド全体が特定のバイト値、一般的には ASCII ゼロで埋められている場合に、そのフィールドをヌルと見なすという前提に基づいています。バイト値は、インデックス作成時に指定するキー定義に指定します。MicroKernel エンジンを使用する場合、MicroKernel エンジンがこの情報から行えることは、フィールドをインデックスに含めるか含めないかだけです。レガシー ヌルは、その特殊な意味にもかかわらず、その他すべての値とまったく同様にソートされる値であるため、特別なソート規則はありません。
キー定義に「全セグメント ヌル」(0x0008)のフラグが含まれている場合、キー内のすべてのセグメントがヌルと見なされると、そのキー値はインデックスに含められません。各セグメントがヌルと見なされるのは、フィールド内のすべてのバイトがヌル バイトである場合です。同様に、キー定義に「一部セグメント ヌル」(0x0200)のフラグが含まれている場合、キー内の 1 つ以上のセグメントがヌルと見なされると、そのキー値はインデックスに含められません。各セグメントがヌルと見なされる規則は前と同じです。
リレーショナル エンジンは、自身が定義するインデックスではこれらのフラグを使用しません。テーブル間の結合を行うためには、テーブル内のすべてのレコードにインデックスを通してアクセス可能でなければならないからです。
真のヌル インデックス
Pervasive.SQL 2000 以降では、「真のヌル」と呼ぶ新しいタイプのヌル インジケーターが導入されています。
真のヌルは、ヌルを許可する列の直前に 1 バイトのヌル インジケーター セグメント(NIS)を置くことにより、MicroKernel エンジンに実装されます。これは、その列がヌルかどうかを示すために通常の列幅に追加された特別なバイトです。このバイトの値がゼロであると、このインジケーターが関連付けられている列が通常の列、つまりヌルでないことを示します。このバイトがその他の値である場合は、その列の値がヌルであることを示します。
真のヌルを使用すると、レガシー ヌルとは異なり、値がゼロの整数とヌルの整数を区別することができます。これはその他の数値フィールドにもあてはまります。このような区別が必要のない場合には、長さ 0 の文字列フィールドはヌルであると判別することができます。
リレーショナル エンジンは、列にインデックスが定義されているかどうかにかかわらず、真のヌル列を識別し使用することができます。ただし、基本のデータ ファイルは、キーに含まれるフィールドしか識別することができません。
Create(14)または
Create Index(31)オペレーションのキー定義で、ヌル値を許可する列の前にヌル インジケーター セグメント(NIS)を追加することによって、MicroKernel エンジンのキー内に真のヌル フィールドを定義することができます。真のヌル キーに関する規則については、
真のヌル キーの規則を参照してください。
MicroKernel エンジンでは NIS のオフセットに関する制約はありませんが、リレーショナル エンジンでは NIS はヌル許可列の直前にあるものと見なします。そのため、レコード内のフィールドを構造化する際は、NIS を使用する可能性のあるすべてのフィールドの前のバイトを、NIS を置く場所として空けておくことをお勧めします。こうしておくことにより、必要になった場合、これらのテーブルに SQL を介してアクセスする能力を維持することができます。
真のヌル キーの規則
この新しいキー タイプを使用するときは、次の規則に従う必要があります。
1 フィールド長は 1 である必要があります。
2 このフィールドは、インデックス内の同類のフィールドの前にある必要があります。言い換えると、複数セグメントのインデックスでは、同類のセグメントの直前に NIS が定義されている必要があります。NIS を最終セグメントまたは唯一のセグメントにすることはできません。
3 NIS の直後のフィールドは NIS の内容の影響を受けます。NIS がゼロの場合、直後のフィールドは非ヌルと見なされます。NIS がゼロ以外の場合、直後のフィールドはヌルと見なされます。
4 NIS のオフセットはその次のフィールドの直前のバイトである必要があります。これが、Zen リレーショナル エンジンがこれらのフィールドの配置として要求する様式です。したがって、このインデックス用のデータ辞書を作成する場合、NIS は制御するフィールドの直前にある必要があります。ただし、トランザクショナル API にはこれを必要条件とするものは何もありません。
NIS 値
ゼロ以外の値はすべて、次のセグメントがヌルであることを表すインジケーターと見なされます。デフォルトで、MicroKernel エンジンはゼロ以外の値の間の区別は行いません。Zen リレーショナル エンジンは現在、このフィールドがヌルであることを示すのに値 1 のみを使用します。ただし、異なるタイプのヌルを区別することはできます。これは、NIS に「大文字小文字無視」フラグを使用して行います。このキー フラグは通常、さまざまな文字列フィールドや文字フィールドにのみ適用可能であるため、NIS で使用した場合、DISTINCT に特別な意味を持たせるためにオーバーロードされます。つまり、異なる NIS 値は区別して扱われ、別個にソートされます。Actian Corporation は、将来の拡張のため最初の 15 の値を予約しています。アプリケーションでさまざまなタイプのヌルに特別な意味を持たせたい場合は、NIS に 16 より大きい値を使用してください。たとえば、より詳細なヌル定義は次のようになります。
•適用外
•未定
•決定不能
•検出不能
•必須(未定)
NIS に DISTINCT フラグ(大文字小文字無視)を追加した場合、これらの非ゼロ値は異なる値として別個にソートされます。
真のヌル値のソート
真のヌル フィールドの値は非決定です。言い換えると、その値は不明です。この定義によれば、どの 2 つのヌル値も互いに等しくなく、ほかのすべてのキー値とも等しくありません。それでも、MicroKernel エンジンはこれらのヌル値を 1 つにまとめる必要があり、ヌルに等しいキー値を見つけることができなければなりません。これを行うため、MicroKernel エンジンは比較の目的に合わせて、真のヌル値がそれぞれ等しいかのように解釈します。ソートしたり、インデックス内でヌル値の場所を検索したりする場合、真のヌル値は互いに等しいかのようにグループ化されます。しかし、重複のないインデックス内に値が既に存在するかどうかを判断しようとしているときは、真のヌルは互いに等しくなくなります。
NIS 内の非ゼロ値はすべて、直後のフィールドがヌルであることを示します。デフォルトの動作では、NIS 内の非ゼロ値はすべて同一値のように扱われ、ヌル許可フィールドがヌルであることを示していると解釈されます。したがって、NIS にさまざまな非ゼロ値を含み、それに続くヌル許可フィールドがさまざまな値を含むレコードを挿入した場合、これらは同一の値として解釈され、重複値の集まりとしてソートされます。
リンク重複キーと真のヌル
このセクションでは、リンク重複キーにいくつかのヌル値を挿入した結果について説明します。
リンク重複キーは、一意の値ごとに単一のキー エントリ、2 つのレコード アドレス ポインターを持ちます。レコード アドレス ポインターの 1 つは最初の重複レコード用で、もう 1 つは重複の連鎖の最後のレコード用です。各レコードには、連鎖内の前および次のレコードへのポインターから成る 8 バイトのオーバーヘッドがあります。連鎖の最後に新しい重複値が追加されるごとに、重複レコードは挿入された順に確実にリンクされます。インデックスに追加する目的では、すべてのヌル値は重複と見なされるので、1 つの連鎖に挿入順にリンクされます。各レコードが NIS および関連するヌル許可フィールドに異なるバイト値を持っていても、この連鎖内の最初と最後のレコードを指すキー エントリが 1 つだけ存在します。NIS キー セグメントが降順に定義されている場合、このキー エントリはインデックス内で先頭になります。それ以外は末尾になります。
繰り返し重複キーと真のヌル
繰り返し重複キーは、インデックス内に現れる各レコードの実際のキー エントリを含みます。レコード自体にオーバーヘッドはなく、レコードごとにそれ自体を指すキー エントリがあります。この種のインデックス内の重複値は、それらが指す物理レコード アドレスによってソートされます。つまり、重複値の順序は予測不能で、たくさんのクライアントによって任意のレコードが挿入および削除される高度な同時使用環境では特にそうなります。
真のヌル値は重複値であるかのように解釈され、ヌル許可フィールドのバイト値ではなく、レコード アドレスによってソートされます。したがって、繰り返し重複キーを使用する場合、真のヌル値を含むレコードはまとめてグループ化されますが、その形式は一定ではありません。NIS セグメントが降順の場合、インデックスの最初に現れ、それ以外の場合は最後に現れます。
重複のないキーと真のヌル
MicroKernel エンジンでは、重複フラグを 1 つも使用しないでインデックスを定義した場合、そのインデックスは重複のない値のみを持っている必要があります。しかし、真のヌル フィールドの値は決定不能であるため、重複と見なすことができません。このため、MicroKernel エンジンでは重複のないキーに複数の真のヌル値を入力できますが、更新操作でそのキーに値が割り当てられたときに、キーの一意性が判断されるものとしています。ただし、これらの値をソートする目的では、MicroKernel エンジンはこれらを重複値であるかのようにまとめてグループ化します。したがって、真のヌル値を含むインデックスのセクションは繰り返し重複のインデックスと類似します。ヌルは物理レコード アドレスによってソートされ、その順序は予測できません。
変更不能キーと真のヌル
いったん変更不能キーに値を設定すると、変更することができません。しかし、真のヌル値は実際の値を持たないため、MicroKernel エンジンでは、真のヌル インデックスに定義されているフィールドのうち一部またはすべてに真のヌル値を持つレコードを挿入しておき、後で更新操作を使用して、これらのフィールド値をヌルから非ヌルに変更することができます。ただし、いずれかのフィールドがいったん非ヌルになったら、変更不能性が適用され、そのフィールドを再度ヌルにしてももはや変更はできません。
Get オペレーションと真のヌル
真のヌル値が決定不能で互いに等しいとは見なされないとしても、真のヌル キー セグメントを持つレコードを検索することができます。
さまざまな Get オペレーションが、以下の手順を使用して真のヌル キーのアドレスを指定することができます。
1 NIS バイトに非ゼロ値を設定します。
2 キー バッファーにキー全体を設定します。
3 真のヌル値が互いに等しいかのように Get オペレーションを実行します。
Get オペレーションの予想される動作を以下に示します。
•Get Equal および Get Greater Than or Equal は前方向でヌルを持つ最初のレコードを返します。
•Get Less Than or Equal は前方向から見てヌルを持つ最後のレコードを返します。
•Get Less Than はヌル値の前のレコードを返します。
•Get Greater Than はヌル値の後のレコードを返します。
これは、通常の重複値での Get オペレーションの動作と一貫性があります。
別個の(Distinct)真のヌル
NIS バイト内の異なる値を区別することができます。前に示したように、デフォルトの動作では NIS 内の非ゼロ値はすべて同じものと見なされます。NIS にどのような値が含まれていても、ゼロでない限り、その後のヌル許可フィールドはヌルです。リレーショナル エンジンは現在、作成するすべての真のヌル インデックス セグメントに対し、このデフォルトの動作を用いています。
しかし、テーブルに異なるタイプのヌル値を格納する場合には、NIS セグメントのキー定義に NOCASE フラグ(0x0400)を追加することができます。これ以後、これを DISTINCT フラグと呼びます。これを行うと、MicroKernel エンジンは異なる NIS 値をそれぞれ他と区別して扱います。
別個の真のヌル セグメントは、それぞれの NIS 値によってグループに分けられます。前に述べたさまざまなタイプのインデックスを構築する際と同じ規則が適用されます。リンク重複キーは各別個の NIS 値に単一のエントリを持ち、そのタイプのヌルの繰り返しの先頭と末尾のポインターを持ちます。繰り返し重複および重複のないキーも、別個の NIS 値によってヌル レコードをグループ化します。降順キーでは、最も高い NIS 値がグループの先頭になり、ゼロ、非ヌル値へと小さい値へソートされます。昇順キーでは、非ヌル レコードが先頭で、NIS 値 1、2、のように続きます。Get オペレーションでは NIS 値に注意が払われます。NIS 値を 20 とするキー バッファーを使用して GetEQ を実行する場合、別個の真のヌル インデックス内のすべての NIS 値が 1 であると、MicroKernel エンジンは一致する値を見つけることができません。
現在は、リレーショナル エンジンもいずれの Zen アクセス方法も、真のヌル インデックスを作成する際に DISTINCT フラグを使用していませんが、将来は使用する予定です。このため、Zen でこれらのヌルのタイプに特定の意味を割り当てることが必要になる場合に備え、NIS 値の 2 から 16 は将来の使用のために予約されています。したがって、トランザクショナル Btrieve API を介してアクセスするレコードで個別のヌル値を使用する場合は、16 より大きい値を使用してください。
マルチ セグメントの真のヌル キー
2 つのヌルを許可する列を含む、マルチ セグメントの真のヌル インデックスについて考えてみます。キーは、実際は 4 つのセグメントのインデックスとして定義されます。最初のセグメントは NIS で、次に最初のヌル許可フィールド、2 番目の NIS、2 番目のヌル許可フィールドと続きます。以下のレコードがファイルに追加された場合にどうなるかを考えます。
"AAA", NULL "BBB", NULL "CCC", NULL NULL, NULL
"AAA", "AAA" "BBB", "AAA" "CCC", "AAA" NULL, "AAA"
"AAA", "BBB" "BBB", "BBB" "CCC", "BBB" NULL, "BBB"
"AAA", "CCC" "BBB", "CCC" "CCC", "CCC" NULL, "CCC"
さらに "BBB", NULL のいくつかの組み合わせ
リレーショナル エンジンは常に、ヌル値が先頭に来る、真のヌル インデックス セグメントを作成します。各 NIS セグメントに降順フラグ(0x0040)を追加してこれを行います。降順フラグは各 NIS および 2 番目のヌル許可フィールドには使用されたが、1 番目のヌル許可フィールドには使用されていないと仮定します。そうすると、これらのレコードは次のようにソートされます。
1 NULL, NULL
2 NULL, "CCC "
3 NULL, "BBB""
4 NULL, "AAA "
5 "AAA", NULL
6 "AAA", "CCC"
7 "AAA", "BBB"
8 "AAA", "AAA"
9 "BBB", NULL
10 "BBB", NULL
11 "BBB", NULL
12 "BBB", "CCC "
13 "BBB", "BBB"
14 "BBB", "AAA "
15 "CCC", NULL
16 "CCC", "CCC "
17 "CCC", "BBB"
18 "CCC", "AAA "
ヌルは常に非ヌルより前に現れます。これは両方の NIS が降順であるためです。ただし、NIS がゼロ、つまりフィールドが非ヌルの場合、最初のフィールドは昇順で 2 番目のフィールドは降順でソートされます。
以下に、さまざまな Get オペレーションで何が返されるかを示します。
GetLT "BBB", NULL が返すレコードは 8 "AAA", "AAA"
GetLE "BBB", NULL が返すレコードは 11 "BBB", NULL
GetEQ "BBB", NULL が返すレコードは 9 "BBB", NULL
GetGE "BBB", NULL が返すレコードは 9 "BBB", NULL
GetGT "BBB", NULL が返すレコードは 12 "BBB", "CCC "
GetLE にはファイルを逆順に調べていくという言外の意味が含まれているため、逆順で最初に「一致」したキー値のレコードを返します。GetEQ および GetGE には前方へ移動するという言外の意味があります。
インデックスからレコードを除外する
レガシー ヌルを使用すると、NIS を含むインデックスの各セグメントに「全セグメント ヌル」(0x0008)または「一部セグメント ヌル」(0x0200)のフラグも適用することができました。レコードを挿入すると、MicroKernel エンジンは NIS を使用してヌル許可フィールドがヌルかどうかを調べます。キー エントリがインデックスに含められるかどうかを決定するのにも同じ規則が使用されます。
メモ:リレーショナル エンジンが作成したファイルはこれらのフラグを使用しません。
したがって、これらのファイルにどこかの時点で SQL からアクセスする可能性があり、目的が「列がヌル」であるレコードを見つけることである場合は、これらのフラグを使用しないでください。リレーショナル エンジンはヌル レコードを検索するのにインデックスを使用しますが、インデックスを介してヌル レコードにはアクセスできません。
Extended オペレーションでのヌル インジケーター セグメントの使用
Extended オペレーションを使用すると、アプリケーションは、そのテーブルのために作成されたインデックスがない場合でも、そのテーブルのフィールドにアクセスすることができます。任意のソースから得られる知識によってレコードのフィールドを実行中に定義することにより、レコード内のフィールドにフィルターを適用することができます。このように、Extended オペレーションで真のヌル フィールドを定義することが可能になり、MicroKernel エンジンはこれらのフィールドをインデックスにソートするのと同じ比較規則を適用することができます。
Extended オペレーションのフィルターは、キーを定義するのと同じように定義する必要があります。NIS のためのフィルター セグメントに続けてヌル許可フィールドのフィルター セグメントを含めます。ヌル値を検索する場合で、ヌル許可フィールドの内容が問題にならない場合であっても、ヌル許可フィールドを含める必要があります。GetNextExtended がインデックス パスに対して最適化されるには、MicroKernel エンジンは両方のフィルター セグメントを必要とします。これらが確実に含められるよう、ステータス 62 によって、NIS のためのフィルター式に続けて非 NIS のフィルター式がなかったことを示します。
NIS で使用できる比較演算子は、EQ または NE のみです。GT、GE、LT、および LE などのほかの比較演算子を使用すると、ステータス 62 が返されます。
Extended オペレーションのディスクリプターが不適切な形式あることにより発生するステータス 62 は、Zen イベント ログにシステム エラーを追加します。これらのシステム エラーは表
2 にリストされており、ステータス 62 の理由を識別するのに役立ちます。
異なる NIS 値を明確に区別して扱いたい場合は、NIS フィルターの比較演算子に 128 を加えます。これは、大文字小文字無視で使用するのと同じバイアス値です。インデックスを定義するときと同様に、非ゼロ値を明確に比較することを示す、つまりこれらがすべて同一として扱われるのではなく、互いに区別されることを示すための大文字小文字無視フラグがヌル インジケーター キー タイプに過負荷をかけてきました。
Extended オペレーションを使用して可能な限り最高のパフォーマンスを得たいなら、特定の限定されたキー値の範囲でキー パスを検索しようとするでしょう。まず最初に、GetGE を使用して範囲の先頭にカレンシーを確立します。次に GetNextExtended を実行します。また、GetLE に続けて GetPrevExtended を実行することができます。これらの Extended オペレーションは、フィルターに合致する値をもう見つけられない場合に自動的に検索を停止します。これは、Extended オペレーションの最適化と呼びます。フィルターで最適化を使用すれば、非常に多くのレコードをファイルから読まずに飛ばすことができるため、さらに効率的になります。最適検索を作成するためには、制限が存在する方向でインデックスを検索する必要があります。また、セグメントの結合には OR の代わりに AND を使用して、フィルターが正確にインデックスと一致するようにする必要があります。
昇順のインデックスで GetNextExtended を実行する場合、最適化フィルターが制限で検索を停止するのは、条件演算子が EQ、LT または LE の場合です。検索は、昇順のインデックスに従って特定の値より大きい値をファイルの終わり方向に向かって探す必要があります。同様に、降順のインデックスの場合、制限で検索を停止するのは条件演算子が EQ、GT または GE の場合です。検索条件に複数のフィールドがある場合、これはさらに複雑になります。簡単な考え方は、フィルターを最適化するには、最後のセグメントのみが EQ 以外の条件演算子を持つことができるということです。これは、NIS を含みます。NIS の条件演算子が NE の場合、フィルターは、前のフィルター セグメントまでしか最適化することができません。
インデックスと正確に合致するということは、各フィルター式がインデックス内のセグメント順に従っており、同じオフセット、長さ、キー タイプ、大文字小文字区別(または DISTINCT フラグ)、および ACS 仕様を持つということです。これらがインデックスと合致していないと、Extended オペレーションは最適化できません。
真のヌルと SQL エンジン
真のヌルは、ヌル インジケーターのキー タイプを使用し、前述の規則に従うことによって、リレーショナル エンジンに実装されます。MicroKernel エンジン アプリケーションも、このキー タイプを使用してヌル可能フィールドがヌルかどうかをその内容にかかわらず識別することができます。これにより、整数とほかの数値データ型のヌルを識別し、これらのヌル可能フィールドを完全に管理することができます。
真のヌルと Extended オペレーション
Extended オペレーションで発生するステータス 62 はディスクリプターが不正であることを示します。ディスクリプターの何が間違っているのかを判断するのがむずかしい場合があります。データベース エンジンは Zen イベント ログに、問題を正確に判断するのに使用できる行を追加しました。イベント ログのエントリは次のようなものです。
05-12-2019 11:12:45 W3MKDE 0000053C zenengnsvc.exe MY_COMPUTER E システム エラー: 301.36.0 ファイル: D:\work\test.mkd
システム エラー 301 から 318 までの番号は、以下の問題を識別します。
表 2 システム エラー コード
システム エラー | 説明 |
---|
301 | ディスクリプター長が不正です。 |
302 | ディスクリプター ID は、EG または UC でなければなりません。 |
303 | フィールド タイプが無効です。 |
304 | 演算子の NOCASE フラグは、文字列およびヌル インジケーター タイプのみで使用できます。 |
305 | 演算子の ACS フラグ(0x08 および 0x20)は、文字列タイプのみで使用できます。 |
306 | バイアスされていない演算子はゼロと同等です。 |
307 | バイアスされていない演算子が 6 より大きいです。 |
308 | 無効な式のコネクタが見つかりました。0、1、2 のみを使用できます。 |
309 | ACS が定義されていません。 |
310 | 最後の式には終端文字が必要です。 |
311 | 最後の式より前に終端文字が見つかりました。フィルター セグメント カウントが不正です。 |
312 | 抽出するレコード数がゼロです。 |
313 | 抽出するフィールド長がゼロです。 |
314 | ヌル インジケーター セグメントの次には別のフィールドが続く必要があります。 |
315 | ヌル インジケーター セグメントは AND で次のセグメントと結合する必要があります。 |
316 | ヌル インジケーター セグメントは EQ または NE のみと使用できます。 |
317 | ヌル インジケーター セグメントの次に別の NIS は続けられません。 |
318 | ヌル インジケーター セグメントの次のフィールドは 255 バイト以下である必要があります。 |
オルタネート コレーティング シーケンス
オルタネート コレーティング シーケンス(ACS)を使用して、文字型のキー(STRING、LSTRING および ZSTRING)を標準 ASCII 照合順序とは異なる順序でソートすることができます。1 つまたは複数の ACS ファイルを使用して、次のようにキーをソートすることができます。
•独自のユーザー定義ソート順序による方法。この方法は、英数字(A~Z、a~z、0~9)を非英数字(# など)と混用するソート順序を必要とするような場合に使用します。
•インターナショナル ソート規則(ISR)による方法。これは、スペイン語の ll のようなマルチバイト照合要素、フランス語の ô のような区分発音符、ドイツ語の ss へ拡張する ß のような文字の拡張および短縮など、言語固有の照合順序に対応しています。
ファイルには、キーごとに異なる ACS を持つことができますが、1 つのキーには 1 つの ACS のみです。したがって、キーがセグメント化されている場合、各セグメントはそのキーに指定された ACS を使用するか、または ACS をまったく使用しないかのいずれかになります。あるファイルに、一部のセグメントにだけ ACS が指定されているキーがある場合、MicroKernel エンジンは指定されたセグメントのみ、ACS を使用してソートします。
ユーザー定義 ACS
ASCII 標準とは別の方法で文字列値をソートする ACS を作成するには、次の表に示す形式を使用します。
位置(オフセット) | 長さ | 説明 |
---|
0 | 1 | 識別バイト。0xAC を指定します。 |
1 | 8 | MicroKernel エンジンに ACS を識別させる、8 バイトの一意の名前。 |
9 | 256 | 256 バイトのマップ。マップ内の 1 バイトの位置はそれぞれ、マップ内でのその位置のオフセットと同じ値を持つコード ポイントに対応します。その位置にあるバイトの値は、コード ポイントに割り当てられる照合重みです。たとえば、コード ポイント 0x61(a)をコード ポイント 0x41(A)と同じ重みでソートさせるには、同じ値をオフセット 0x61 と 0x41 に設定します。 |
ACS ファイルは 16 進エディターで作成されるか、MicroKernel エンジン アプリケーション内に定義されるので、主にユーザー定義 ACS ファイルはアプリケーション開発者には有用ですが、一般にエンド ユーザーによっては作成されません。
以下に、UPPER という照合順序を表す 9 バイト ヘッダーと 256 バイト本体を示します。ヘッダーは以下のとおりです。
AC 55 50 50 45 52 20 20 20
256 バイト本体は以下のようなものですが、左端の列にオフセットが付けてあります。
00: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10: 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20: 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30: 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40: 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
50: 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60: 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
70: 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F
80: 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
90: 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
A0: A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
B0: B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
C0: C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
D0: D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF
E0: E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
F0: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF
この ACS を構成するヘッダーと本体は、ファイル UPPER.ALT として Zen に付属しています。UPPER.ALT は、大文字小文字に関係なくキーをソートする方法を提供します(大文字と小文字を区別しないようにキーを定義することができますが、UPPER は独自の ACS を書くときに良い見本になります)。
例に示すオフセット 0x61~0x7A は、標準の ASCII 照合順序から変更されています。標準 ASCII では、オフセット 0x61 には値 0x61(小文字の a)が含まれています。UPPER ACS を使用してキーをソートする場合、MicroKernel エンジンは小文字の a(0x61)を、オフセット 0x61 の照合重みである 0x41 を使ってソートします。このように、小文字 a は大文字 A(0x41)であるかのようにソートされます。したがって、ソートの目的のために、UPPER はキーのソート時に、すべての小文字をそれらに相当する大文字に変換します。
次に示す 256 バイトの本体は、ASCII スペース(0x20)の前の ASCII 文字が他のすべての ASCII 文字の後にソートされる点を除き、UPPER.ALT の本体と同じ機能を果たします。
00: E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
10: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF
20: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
30: 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
40: 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
50: 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
60: 40 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
70: 30 31 32 33 34 35 36 37 38 39 3A 5B 5C 5D 5E 5F
80: 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
90: 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
A0: 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
B0: 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
C0: A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
D0: B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
E0: C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
F0: D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF
この本体では、別の照合重みが割り当てられているので、文字の重みがもう ASCII 値と同じではありません。たとえば、ASCII スペース文字を表すオフセット 0x20 の照合重みは 0x00 です。ASCII の大文字 A を表すオフセット 0x41 の照合重みは 0x21 です。
大文字小文字に関係なくキーをソートするために、最後の例のオフセット 0x61~0x7A は変更されています。UPPER.ALT の本体と同様に、オフセット 0x61 はオフセット 0x41 と同じ照合重み、つまり 0x21 を持っています。同じ照合重みを持つことにより、オフセット 0x41(A)はオフセット 0x61(a)と同じようにソートされます。
インターナショナル ソート規則
ISO で定義された言語固有の照合順序を使用して文字列をソートする ACS を指定するには、次の例に示すように ISR テーブル名を指定する必要があります。
表 3 ISR テーブル名
ロケール/言語 | コード ページ | ISR テーブル名 |
---|
アメリカ/英語 | 437 MS-DOS Latin-US 850 MS-DOS Latin-1 | PVSW_ENUS00437_0 PVSW_ENUS00850_0 |
フランス/フランス語 | 437 MS-DOS Latin-US 850 MS-DOS-Latin-1 | PVSW_FRFR00437_0 PVSW_FRFR00850_0 |
ドイツ/ドイツ語 | 437 MS-DOS Latin-US 850 MS-DOS Latin-1 | PVSW_DEDE00437_0 PVSW_DEDE00850_0 |
スペイン/スペイン語 | 437 MS-DOS Latin-US 850 MS-DOS Latin-1 | PVSW_ESES00437_0 PVSW_ESES00850_0 |
日本/日本語 | 932 シフト JIS | PVSW_JPJP00932_1 |
ISR テーブルは ISO の標準ロケール テーブルに基づいており、Zen によってインストールされます。ISR テーブルは Zen のデータベース エンジンと一緒にインストールされた collate.cfg ファイルに格納されています。データ ファイルは 1 つの ISR を共有できます。
キー仕様
Create(14)または Create Index(31)を使用してインデックスを作成する場合は、キー仕様構造体を提供する必要があります。
キー仕様ブロック
次の表は、キー仕様のデータ バッファー構造体を示しています。各キー仕様ブロックは、BTRV タイプのエントリ ポイントの場合は 16 バイト、BTRVEX タイプのエントリ ポイントの場合は 24 バイトです。2 つのデータ型が示されている場合、1 つめは BTRV で使用され、2 つめは BTRVEX で使用されます。
フィールド | データ型1 | 長さ | NIS セグメント | 説明 |
---|
キー ポジション | Short Int2 | 2 | レコードの固定長部分でのオフセット | レコード内のキーの相対位置 |
キー長 | Short Int2 | 2 | 1 | キーの長さ。 |
キー フラグ | Short Int2 | 2 | xxxxxxx1xxx1xxxx FEDCBA9876543210 | |
予約済み(ワイド) | Byte | 0 または 2 | 適用外 | BTRV タイプのエントリ ポイントの場合は指定しない、BTRVEX タイプのエントリ ポイントの場合は 2 バイト。Create(14)では使用されません。下位バージョンとの互換性を保つために 0 に初期化します。 |
一意キー | Int または Long Long Int2 | 4 または 8 | 適用外 | BTRV タイプのエントリ ポイントの場合は 4 バイト、BTRVEX タイプのエントリ ポイントの場合は 8 バイト。Create(14)では使用されません。下位バージョンとの互換性を保つために 0 に初期化します。 |
拡張データ型 | Byte または Short Int2 | 1 または 2 | 255(0xFF) | 拡張データ型のうちの 1 つを指定します。新しいデータ型の NULL_INDICATOR が定義されました。BTRV タイプのエントリ ポイントの場合は 1 バイトの Byte 型、BTRVEX タイプのエントリ ポイントの場合は 2 バイトの Short int 型。 |
ヌル値(非インデックス値) | Byte | 1 | 適用外 | キーの除外値を指定します。 |
予約済み | Short Int2 または Byte | 2 または 1 | 適用外 | BTRV タイプのエントリ ポイントの場合は 2 バイト、BTRVEX タイプのエントリ ポイントの場合は 1 バイト。Create(14)では使用されません。下位バージョンとの互換性を保つために 0 に初期化します。 |
手動割り当てキー番号 | Byte または Short Int2 | 1 または 2 | | キー番号BTRV タイプのエントリ ポイントの場合は 1 バイトの Byte 型、BTRVEX タイプのエントリ ポイントの場合は 2 バイトの Short int 型。 |
ACS(オルタネート コレーティング シーケンス)番号 | Byte | 1 | 適用外 | オルタネート コレーティング シーケンス(ACS)番号 |
予約済み(ワイド) | Byte | 0 または 1 | 適用外 | BTRV タイプのエントリ ポイントの場合は指定しない、BTRVEX タイプのエントリ ポイントの場合は 1 バイト。Create(14)では使用されません。下位バージョンとの互換性を保つために 0 に初期化します。 |
1 特に指定がない場合、すべてのデータ型は符号なしです。 2 Integer は「リトル エンディアン」のバイト順、つまり、Intel 系のコンピューターが採用している下位バイトから上位バイトへ記録する方式で格納する必要があります。 |
キー フラグの値
次の表は、キー仕様ブロック内のキー フラグの値を示しています。
属性 | 2 進数 | 16 進数 | 説明 |
---|
重複 | 0000 0000 0000 0001 | 0x0001 | |
変更可能 | 0000 0000 0000 0010 | 0x0002 | |
バイナリ | 0000 0000 0000 0100 | 0x0004 | |
ヌル キー(全セグメント) | 0000 0000 0000 1000 | 0x0008 | |
セグメント | 0000 0000 0001 0000 | 0x0010 | |
ACS | 0000 0000 0010 0000 | 0x0020 | |
ソート順序 | 0000 0000 0100 0000 | 0x0040 | |
繰り返し重複 | 0000 0000 1000 0000 | 0x0080 | |
拡張データ型 | 0000 0001 0000 0000 | 0x0100 | |
ヌル キー(一部セグメント) | 0000 0010 0000 0000 | 0x0200 | |
大文字と小文字の区別(Distinct) | 0000 0100 0000 0000 | 0x0400 | |
既存の ACS | 0000 1000 0000 0000 | 0x0800 | 内部使用のみ |
予約済み | 0001 0000 0000 0000 | 0x1000 | |
ページ圧縮 | 0010 0000 0000 0000 | 0x2000 | |
ペンディング キー | 1000 0000 0000 0000 | 0x8000 | 内部使用のみ |
セグメント キー特有のキー フラグ SEGMENTED(0x0010)、EXTENDED DATA TYPE(0x0100)は、NIS と共に ON に設定する必要があります。
OFF にする必要があるフラグはありません。
フラグ BINARY(0x0004)、ACS(0x0020)は無視されます。
制限と影響
真のヌルのサポートにはいくつかの制限があります。
•参照整合性。現在 MicroKernel エンジンは、DELETE の CASCADE および RESTRICT アクション、UPDATE の RESTRICT アクションのみをサポートしています。SQL-92 は、delete および update の両方に CASCADE、RESTRICT、SET DEFAULT および SET NULL を定義しています。
•セグメント数の制限。ヌル値を許可する列ごとに 2 つのセグメントを占めるため、キーのインデックス付けに使用されるインデックス セグメントの数は増加します。一方、次の表に示されるように、データ ファイルあたりのインデックス セグメントの最大数は同じです。
ページ サイズ(バイト数) | キー セグメントの最大数(ファイル バージョン別) |
---|
8.x 以前 | 9.0 | 9.5 | 13.0 |
---|
512 | 8 | 8 | 切り上げ2 | 切り上げ2 |
1024 | 23 | 23 | 97 | 切り上げ2 |
1536 | 24 | 24 | 切り上げ2 | 切り上げ2 |
2048 | 54 | 54 | 97 | 切り上げ2 |
2560 | 54 | 54 | 切り上げ2 | 切り上げ2 |
3072 | 54 | 54 | 切り上げ2 | 切り上げ2 |
3584 | 54 | 54 | 切り上げ2 | 切り上げ2 |
4096 | 119 | 119 | 2043 | 1833 |
8192 | N/A1 | 119 | 4203 | 3783 |
16384 | N/A1 | N/A1 | 4203 | 3783 |
1 N/A は「適用外」を意味します。 2 「切り上げ」は、ページ サイズを、ファイル バージョンでサポートされる次のサイズへ切り上げることを意味します。たとえば、512 は 1024 に切り上げられ、2560 は 4096 に切り上げるということです。 3 9.5 以降の形式のファイルでは 119 以上のセグメントを指定できますが、インデックスの数は 119 に制限されます。 |
データベース URI
Btrieve ログイン API や、Create または Open オペレーションによる暗黙のログイン機能を使用する上での主要な概念は、データベース URI(Uniform Resource Indicator)です。URI は、サーバー上のデータベース リソースのアドレスを記述する構文を提供します。
このトピックでは、Btrieve API で使用する URI の構文と意味を説明します。
構文
URI は次の構文を使用します。
access_method://user@host/dbname?parameters
要素を省略する場合でも、各要素を区切る特殊文字は必要です。
表 4 データベース URI の要素
要素 | 定義 |
---|
access_method | データベースのアクセスに使用する方法。この要素は必須です。現在、btrv のみがサポートされています。 |
user@ | ユーザー名(省略可能)。必要な場合は、parameters にユーザーのパスワードを指定します。"@" 文字は、host が指定されない場合でも、ユーザー名を区切るために使用する必要があります。 |
host | データベースが保存されているサーバー。host が指定されていない場合は、ローカル マシンと見なされます。host には、マシン名、IP アドレス、または "localhost" キーワードを指定でき、ポートを含めることができます。たとえば、btrv://servername:port/database 要素を含む URI を使用して、デフォルトのポートを上書きすることができます。 メモ:host 要素は、Linux、macOS、または Raspbian のデータベースにアクセスする URI の場合には必須です。 |
dbname | データベース名(省略可能)。データベース エンジンの DBNAMES.CFG ファイル内のエントリに対応します。データベース名が指定されていない場合は、デフォルトのデータベース DefaultDB と見なされます。 |
parameters | 追加オプション パラメーター。アンパサンド(&)文字で区切ります。 •table=テーブル - SQL テーブル名。テーブル名はデータベースの DDF に存在している必要があります。 •dbfile=ファイル - ファイルの名前。ファイルの場所は、現在のデータベースに対する、DBNAMES.CFG 内のデータ ファイルの場所のエントリに関連しています。相対パスが指定されるので、ドライブ文字や、絶対パス、UNC パスの使用は許可されません。データベース エンジンは完全なファイル名を解決します。いかなる方法であっても、Zen クライアントによって「ファイル」が操作されることはありません。空白の埋め込みは可能です。それらの空白はデータベース エンジンによってエスケープされます。 •file=ファイル - データ ファイル名。クライアントはデータベース エンジンへ要求を送る前に、ファイルを正規化し、URI 内の入力名をその結果の完全修飾 UNC 名で置き換えます。ドライブ文字を使用でき、そのドライブはクライアント側のドライブとして解釈されます。スペースを含む UNC パスを使用することも可能です。 •pwd=パスワード - クリア テキスト パスワード。クライアントは転送する前に、クリア テキスト パスワードを暗号化パスワードに変更します。 •prompt=[yes|no] - データベース エンジンからステータス 170(ユーザー名が不正であるか見つからないため、ログインに失敗しました)または 171(パスワードが不正なため、ログインに失敗しました)が返されたとき、ログイン ダイアログ ボックスのポップアップをどのように処理するかをクライアントに知らせます。prompt=yes と指定した場合、リクエスターは[ クライアント資格情報の入力要求]がオフに設定されている場合でも、常にログイン ダイアログ ボックスを表示します。prompt=no と指定した場合、リクエスターは、アプリケーションはステータス 170/171 を直接受け取って、リクエスターにダイアログ ボックスを表示させたくないものと見なします。これは、170 または 171 ステータス コードに対して、認証の入力要求をアプリケーションで処理したい場合に有用です。"yes" または "no" 以外の値は無視されます。リクエスターは[ クライアント資格情報の入力要求]設定に基づいてログイン ダイアログ ボックスを表示します。このオプションは、クライアントの役割を果たしている Linux および macOS では無視されます。 |
パラメーターの優先順位
パラメーターの file、table、および dbfile のうち、2 つ以上のパラメーターが URI に指定された場合、データベース エンジンはそれらのパラメーターに対し優先順位を設定します。つまり、データベース エンジンは URI の解析後、優先順位が最も高いパラメーターを残します。同じ優先度を持つパラメーターが 2 つ以上指定された場合は、解析後、URI で最後に指定されているパラメーターが残ります。
優先順位は file、table、dbfile の順で設定されています。
優先順位の例
初期 URI 文字列 | 解析後 URI 文字列 |
---|
btrv:///?file=MyFile.btr&table=MyTable&dbfile=DataFile.btr | btrv:///?file=MyFile.btr |
btrv:///?table=MyTable&dbfile=DataFile.btr | btrv:///?table=MyTable |
btrv:///?dbfile=DataFile.btr&file=MyFile.btr | btrv:///?file=MyFile.btr |
btrv:///?dbfile=DataFile.btr | btrv:///?dbfile=DataFile.btr |
btrv:///?file=FileOne&file=FileTwo | btrv:///?file=FileTwo |
btrv:///?table=TableOne&table=TableTwo&file=MyFile.btr | btrv:///?file=MyFile.btr |
特殊文字
ほかの URI と同様に、ある特定の英数字以外の文字は URI 構文で特殊な意味を持ちます。そのような文字の 1 つを URI のいずれかの要素で使用する場合は、その文字が実際のテキストではなく特殊文字であると識別されるよう、エスケープ シーケンスを使用する必要があります。エスケープ シーケンスは、特殊文字に相当するプレーン テキストを表す、別の特殊文字または文字の組み合わせです。
下記の表は、MicroKernel エンジン URI の構文でサポートされている特殊文字と、それに関連付けられたエスケープ シーケンス(パーセント記号と、指定された文字の 16 進値で表されます)を示しています。
表 5 データベース URI における特殊文字
文字 | 説明 | 16 進値 |
---|
/ | ディレクトリとサブディレクトリを区切ります。 | %2F |
? | ベース URI と関連パラメーターを分離します。 | %3F |
% | 特殊文字を指定します。 | %25 |
# | ブックマークまたはアンカーを示します。 | %23 |
& | URI 内のパラメーターを区切ります。 | %26 |
" " | 二重引用符で囲まれている内容全体を示します。 | %22 |
= | パラメーターとその値を区切ります。 | %3D |
空白 | 特別な意味はありませんが、予約されています。 | %20 |
: | ホストとポートを分離します(予約されていますが、現在はサポートされていません)。コロンは IPv6 アドレスでも一部使用されます。 IPv6 を参照してください。 | %3A |
空白文字は URI 仕様で予約されていますが、これは区切り文字として使用されないため、引用符もエスケープ シーケンスもなしで使用できます。それ以外の上記の表内の記号は区切り文字として使用されるため、エスケープする必要があります。
例
このセクションでは、フィールド値の中で使用されている特殊文字を識別するためにエスケープ シーケンスを使用している URI の例を示します。
表 6 エスケープ シーケンスを含んでいる URI の例
URI | 意味 |
---|
btrv://Bob@myhost/demodata?pwd= This%20Is%20Bob | ユーザー名が "Bob" でパスワードが "This Is Bob" |
btrv://Bob@myhost/demodata?pwd= This Is Bob | ユーザー名が "Bob" でパスワードが "This Is Bob" |
btrv://myhost/mydb?file=c:/data%20files/pvsw/mydb/c.mkd | %20 は空白文字を表します。開くファイルは "C:\data files\pvsw\mydb\c.mkd" です。 |
btrv://Bob@myhost/demodata?pwd= mypass%20Is%20%26%3f | ユーザー名が "Bob" でパスワードが "mypass Is &?" |
備考
空のユーザー名または空のパスワードは、ユーザー名やパスワードがないこととは異なるので注意してください。たとえば、btrv://@host/ には空のユーザー名が入っていますが、btrv://host/ にはユーザー名がありません。btrv://sam@host/?pwd= には、"sam" というユーザー名が入っており、パスワードは空です。
URI によっては user:password 構文を使用することもできます。ただし、ここで指定されるパスワードはその後クリア テキストとして転送されます。パスワードがクリア テキストとして転送されないようにするため、user:password 構文を使用してパスワードが提供された場合、Zen データベース URI はそのパスワードを無視します。pwd= パラメーターを使用してパスワードを提供してください。このパスワードは Zen クライアントによって転送される前に暗号化パスワードへ変更されます。
URI によっては、user@host:port 構文を使用するサーバー ベースの命名機関を可能にすることもできます。Zen データベース URI は port 要素の指定をサポートします。
例
URL(Uniform Resource Locator)は単に、インターネット上のファイルまたはリソースのアドレスです。データベース URI は同じ概念を利用してサーバー上のデータベースのアドレスを指定します。このトピックでは、Zen データベースにおける、特に MicroKernel エンジン アクセスを使用する場合の URI の構文と意味の例を挙げます。
表 7 MicroKernel エンジン URI の例
例 | 意味 |
---|
btrv://myhost/demodata | サーバー myhost 上のデータベース demodata。サーバーのオペレーティング システムは、Zen でサポートされる OS のいずれかになります。 |
btrv:///demodata | ローカル マシン上のデータベース demodata。ローカル マシンは Windows オペレーティング システムを実行しています。Linux および macOS システムでは host 要素が必須です(上の例を参照)。 |
btrv://Bob@myhost/demodata | パスワードなしのユーザー名 Bob で、サーバー myhost 上のデータベース demodata にアクセスします。 |
btrv://Bob@myhost/mydb?pwd=a4 | ユーザー名 Bob、パスワード "a4" で、サーバー myhost 上のデータベース mydb にアクセスします。 |
btrv://myhost/demodata?table=class | 不特定のユーザーが、サーバー myhost 上のデータベース "demodata" 内のデータベース テーブル class にアクセスします。 |
btrv://myhost/?table=class | 不特定のユーザーが、サーバー myhost 上のデフォルト データベース(DefaultDB)内のデータベース テーブル class にアクセスします。 |
btrv://myhost/mydb?file=f:/mydb/a.mkd | 不特定のユーザーが、サーバー myhost 上のデータベース mydb のセキュリティ資格情報を使用して、クライアントから見たデータ ファイル "F:/mydb/a.mkd" にアクセスします。 クライアントはドライブ F を標準化する、つまり、クライアントでドライブをサーバー myhost に割り当てる必要があることに留意してください。 |
btrv://mydb?file=c:/mydb/a.mkd | 不特定のユーザーが、ローカル マシン上のデータベース mydb 下のデータ ファイル C:/mydb/a.mkd にアクセスします。 ドライブ C は、ローカル マシン上のローカル ドライブです。ローカル マシンは Windows オペレーティング システムを実行しています。 |
btrv://myhost/demodata?dbfile=class.mkd | 不特定のユーザーが、サーバー myhost 上のデータベース demodata に定義されたデータ ディレクトリのうちの 1 つにある、データ ファイル class.mkd にアクセスします。ファイル名が file= ではなく dbfile= で指定されているため、クライアント リクエスターはファイル名 class.mkd を正規化しません。class.mkd を絶対パスに正規化するのは、サーバー エンジンのみです。 |
IPv6
URI および UNC 構文では、コロンなど一部の特殊文字を使用できません。未加工の IPv6 アドレスではコロンを使用するので、UNC パスや URI 接続の処理には異なる方法を使用できます。Zen は IPv6-literal.net 名および、角かっこ([])で囲まれた IPv6 アドレスをサポートします。
『
Getting Started with Zen』の
ドライブ ベースの形式を参照してください。
ダブルバイト文字のサポート
Zen は、ファイル パス内にシフト JIS(日本工業規格)でコード化されたダブルバイト文字を受け入れます(シフト JIS は、日本語のコンピューターに一般に使用されるコード化の手法です)。また、レコードにシフト JIS ダブルバイト文字を格納し、
インターナショナル ソート規則で説明した日本語 ISR テーブルでそれらの文字をソートします。他のマルチバイト文字はレコードに格納できますが、ISR テーブルは文化的に正しい規則に従ってこれらのレコードをソートする目的には現在使用できません。ダブルバイト文字を使用しても、Zen アプリケーションのオペレーションに影響を与えません。
レコード長
すべてのレコードには、レコード長、あるレコードのキーを含むすべてのデータを取り込めるだけの十分な大きさが必要な固定長部分、および、データ ページにレコードを格納するのに必要なオーバーヘッドが含まれています。
物理レコード長を算出するために論理レコード長に追加しなければならないオーバーヘッドのバイト数については、
レコードの圧縮を使用しない場合のレコード オーバーヘッドのバイト数および
レコードの圧縮を使用した場合のレコード オーバーヘッドのバイト数を参照してください。
次の表は、固定長レコードの最大レコード サイズの一覧です。
表 8 固定長レコードの最大レコード サイズ(バイト単位)
ファイル バージョン | システム データ不使用1 | システム データ使用2 | システム データ v2 使用3 |
---|
7.x | 4088(4096 - 8) | 4080(4088 - 8) | |
8.x | 4086(4096 - 10) | 4078(4086 - 8) | |
9.0 ~ 9.4 | 8182(8192 - 10) | 8174(8182 - 8) | |
9.5 | 16372(16384 - 12) | 16364(16372 - 8) | |
13.0 | 16364(16384 - 20) | 16356(16364 - 8) | 16348(16364 - 16) |
1 ページ オーバーヘッドとレコード オーバーヘッドを最大ページ サイズから減算して、最大レコード サイズを決定します。レコード オーバーヘッドは、各ファイル形式で 2 バイトです。 2 システム データには、8 バイトの追加オーバーヘッドが必要です。 3 システム データ v2 には、16 バイトの追加オーバーヘッドが必要です。 |
ファイルがシステム データを使用し、レコード長が上記の表に示した制限を超える場合、データベース エンジンではそのファイルに対し、データ圧縮を行うことに注意してください。
オプションとして、ファイル内のレコードには可変長部分を含めることができます。可変長レコードには、すべてのレコード内で同じサイズである固定長部分と、各レコードでサイズの異なる可変長部分があります。可変長レコードを使用するファイルを作成する場合、固定長の長さは各レコードの最大長です。最大レコード長は定義しません。
理論的には、可変長レコードの最大長は MicroKernel エンジンのファイル サイズの上限によってのみ制限されます。これは、13.0 バージョンのファイルではテラバイトまで、9.5 バージョンでは 256 GB、9.x より前のバージョンでは 128 GB、それ以前のバージョンでは 64 GB です。実際に、最大長はオペレーティング システムやシステム リソース、レコード アクセス方法などの要因により制限されます。レコード全体を取得、更新、または挿入する場合、データ バッファー長パラメーターは 16 ビット符号なし整数であるため、レコード長を 65535 までに制限します。
実行するオペレーションによって異なりますが、データ バッファーは各種情報の転送に使用する MicroKernel エンジン関数パラメーターです。データ バッファーには、レコード全体、レコードの一部、ファイル仕様などが含まれます。データ バッファーの詳細については、
データベースの設計の表
11 を参照してください。
メモ:データと内部ヘッダー情報の合計バイトは、64 KB(0x10000)バイトを超えることはできません。MicroKernel エンジンは、内部の目的で 1024(0x400)バイトを予約します。つまり、64512(0xFC00)バイトのデータを持つことができます。
ファイルが非常に大きいレコードを使用する場合は、ファイル内の可変長部割り当てテーブル(VAT)を考慮してください。リンク済みリストとして実装されている VAT は、レコードの可変長部分へのポインターの配列です。VAT は、非常に大きいレコードの各部分へのランダム アクセスを加速します。非常に大きいレコードの例として、バイナリ ラージ オブジェクト(BLOB)やグラフィックスがあります。
非常に大きい可変長レコードを含むファイルについて、MicroKernel エンジンは多数の可変ページにまたがってレコードを分割し、可変長部と呼ぶリンク済みリストでこれらのページを接続します。アプリケーションがチャンク オペレーションを使用してレコードの一部にアクセスし、レコードの一部がレコード自体の先頭を越えたオフセットから始まる場合、MicroKernel エンジンはそのオフセットをシークするための可変長部リンク済みリストの読み取りにかなりの時間を費やすことがあります。そのようなシーク時間を制限するために、ファイルが VAT を使用するように指定できます。MicroKernel エンジンは可変ページに VAT を格納します。VAT を含むファイルでは、可変長部分を持つ各レコードにそれ自体の VAT があります。
MicroKernel エンジンが VAT を使用するのは、ランダム アクセスを加速するためだけでなく、データ圧縮時に使用される圧縮バッファーのサイズを制限するためでもあります。ファイルでデータ圧縮を使用する場合、そのファイルで VAT を使用する必要があります。
データ整合性
以下の機能は、マルチユーザー環境でファイルの整合性を保証しながら、並行アクセスをサポートします。
レコード ロック
アプリケーションは、明示的に、一度に 1 レコード(単一レコード ロック)または一度に複数のレコード(複数レコード ロック)をロックできます。アプリケーションは、レコード ロックを指定する場合、ウェイトまたはノーウェイト条件を適用することもできます。アプリケーションが現在使用できないレコードに対するノーウェイト ロックを要求する場合、つまり、レコードが既に別のアプリケーションでロックされているか、ファイル全体が排他トランザクションでロックされている場合、MicroKernel エンジンはロックを許可しません。
アプリケーションが使用できないレコードに対するウェイト ロックを要求すると、MicroKernel エンジンはデッドロック状態の有無を確認します。デッドロック検出ステータス コードが返されるまで待機するように、MicroKernel エンジンを設定することができます。これを行うと、MicroKernel エンジンを内部的に待機させてアプリケーションにはオペレーションを再試行させないので、マルチユーザー環境におけるパフォーマンスを向上させます。
トランザクション
ファイルに対して行う変更が多く、また、これらの変更をすべて行うか、またはまったく行わないかを確実にしなければならない場合は、トランザクションでこれらの変更を行うためのオペレーションを取り込みます。明示的なトランザクションを定義すれば、MicroKernel エンジンに複数のオペレーションをアトミックな単位として処理させることができます。ほかのユーザーは、トランザクションが終了するまでファイルに対して行われた変更がわかりません。MicroKernel エンジンは、排他トランザクションと並行トランザクションの 2 種類のトランザクションをサポートします。
排他トランザクション
排他トランザクションでは、MicroKernel エンジンはデータ ファイルのレコードを挿入、更新、または削除するとき、そのデータ ファイル全体をロックします。ほかのアプリケーションや同じアプリケーションの別のインスタンスは、ファイルを開いてそのレコードを読み取ることはできますが、ファイルを変更することはできません。ファイルは、アプリケーションがトランザクションを終了または中止するまで、ロック状態のままになります。
並行トランザクション
並行トランザクションでは、MicroKernel エンジンは、実行するオペレーションによってファイル内のレコードまたはページをロックします。MicroKernel エンジンは、複数のアプリケーション(または同じアプリケーションの複数のインスタンス)が同じファイルの異なる部分に並行トランザクション内で変更を行えるようにしますが、それはこれらの変更が既にロックされているほかのファイル部分に影響を与えない場合に限られます。レコードまたはページは、アプリケーションがトランザクションを終了または中断するまで、ロック状態のままになります。並行トランザクションは、6.0 以降のファイルのみに使用できます。
排他と並行
たとえ要求されたレコードを並行トランザクションが既にロックしていても、クライアントはこれまでどおりレコードを読み取ることができます。ただし、これらのクライアントは排他トランザクション内から処理を行えません。また、要求されたレコードを含むファイルが排他トランザクションで現在ロックされているか、要求されたレコードを並行トランザクションが既にロックしている場合、クライアントは読み取り操作にロック バイアスを適用できません。
クライアントが排他ロックでレコードを読み取ると、MicroKernel エンジンは個々のレコードだけをロックし、レコードが存在するページの残りの部分はロックされない状態のままになります。
メモ:トランザクション内からファイルを開くだけでは、レコード、ページまたはファイルはロックされません。また、MicroKernel エンジンは、読み取り専用のフラグを立てたファイルや読み取り専用モードで開いたファイルはロックしません。
排他トランザクションを使用する場合、Begin Transaction(19 または 1019)オペレーションにノー ウェイト バイアスが付加されない限り、MicroKernel エンジンはロックされたファイルでほかのクライアントを暗黙に待機させます。アプリケーションは、この暗黙の待機状態でハングしたように見えます。これらの排他トランザクションの寿命が短いと、待機時間に気が付かない場合があります。ただし、暗黙の待機を必要とする多くのクライアントの影響によって、大量の CPU 時間が使用されます。さらに、同じファイル内の複数のポジション ブロックはロックを共有します。
暗黙の待機を必要とする排他トランザクションも、ネットワーク帯域幅を無駄に使用しています。MicroKernel エンジンは、リクエスターに戻る前に約 1 秒間待機します。リクエスターは待機状態を認識し、MicroKernel エンジンに操作を返します。したがって、排他トランザクションは余計なネットワーク トラフィックを発生させる可能性もあります。
余計な CPU サイクルとネットワーク トラフィックの量は、ロック済みファイルで待機しているクライアント数と排他トランザクションで必要な時間と相まって、幾何級数的に増加します。
トランザクション一貫性保持
すべてのオペレーションを 1 つのトランザクション ログに記録することによって、
トランザクション一貫性保持とアトミシティを保証するように MicroKernel エンジンを設定できます。トランザクション一貫性保持は、クライアントが End Transaction オペレーションを発行したときと、MicroKernel エンジンが正常終了したステータス コードをクライアントに返す前に、MicroKernel エンジンがログへの書き込みを終了することを保証する機能です。アトミシティは、特定のステートメントが終わりまで実行しない場合にそのステートメントがデータベース内に部分的または不明確な影響を残さないように保証し、それによってデータベースを安定した状態に保つことでデータベースの整合性を保証します。
トランザクション一貫性保持のオーバーヘッドなしでアトミシティが必要な場合は、PSQL V8 以降のリリースのトランザクション ログ機能を使用することができます。トランザクション ログの詳細については、『Advanced Operations Guide』を参照してください。
デフォルトのインストールでは、トランザクション ログは C:\ProgramData\Actian\Zen\logs にあります。ログは、Zen エンジンと同じマシン上に存在しなければなりません。この場所は、ZenCC でトランザクション ログ ディレクトリ設定オプションを使用して変更できます。MicroKernel エンジンを右クリックし、[プロパティ]>[ディレクトリ]の順に選択すると表示されます。
MicroKernel エンジンは、ログ セグメントと呼ぶ 1 つまたは複数の物理ファイルでトランザクション ログを保持します。現在のログ セグメントがユーザー定義のサイズ上限に達し、変更が待機状態であるファイルがなく、MicroKernel エンジンがシステム トランザクションを終了すると、MicroKernel エンジンは新しいログ セグメントを開始します。
すべてのトランザクション ログ セグメントには必ず .log というファイル拡張子が付きます。MicroKernel エンジンはログ セグメントのファイル名として、00000001.log、00000002.log、.... のように、8 桁の 16 進数を使った連続する番号を使用します。
特定ファイルのパフォーマンスを向上させるために、アクセラレイティド モードでファイルを開くことができます(バージョン 6.x MicroKernel エンジンはアクセラレイティド オープン要求を受け入れましたが、それらの要求をノーマル オープン要求と解釈していました)。アクセラレイティド モードでファイルを開くと、MicroKernel エンジンは、そのファイルに対するトランザクション ログを実行しません。
メモ:システム障害が発生すると、起動時に削除されないログ セグメントが生成される場合があります。これらのセグメントは、データ ファイルに完全に書き込まれなかった変更を含みます。これらのログ セグメントを削除しないで下さい。どのファイルがこれらのログ セグメントに書き込まれているかはわかりません。これらのデータ ファイルは、次回開かれたときに自動的にロール フォワードするので、何もする必要はありません。
システム データ
Zenは、7.x トランザクション ログ ファイル形式を使用します。MicroKernel エンジンがファイルでトランザクションのログを記録するには、MicroKernel エンジンがログ内のレコードを追跡する際に使用できる重複のない(重複不可能)キーであるログ キーがファイルに含まれている必要があります。1 つ以上の重複のない(重複不可能)キーを持つファイルの場合、MicroKernel エンジンはファイルで既に定義されている重複のないキーのうちの 1 つを使用します。
重複のないキーを持たないファイルの場合、MicroKernel エンジンはファイル作成時にシステム データを含めることができます。MicroKernel エンジンはファイルが 7.x 以降のファイル形式を使用している場合だけファイルにシステム データを含めます。その時点でファイルを作成する場合は、ファイル作成時にファイルにシステム データを含めるように MicroKernel エンジンが設定されます。システム データは、8 バイトのバイナリ値としてキー番号 125 で定義されます。ファイルに重複のないユーザー定義キーがある場合でも、ユーザーによるインデックスの削除に備えるために、システム データ(システム定義のログ キーとも呼ばれます)を使用することができます。
ファイルがシステム データを使用し、レコード長が表
8 に示した制限を超える場合、データベース エンジンではそのファイルに対し、データ圧縮を行います。
MicroKernel エンジンがシステム データを追加するのはファイル作成時だけです。既存のファイルにシステム データを追加する場合は、[システム データの作成]設定オプションをオンにしてから Rebuild ユーティリティを使用します。
メモ:MicroKernel エンジンがシステム データを追加すると、その結果、レコードが大きすぎてファイルの既存のページ サイズに収まらない場合があります。その場合、MicroKernel エンジンは、ファイルのページ サイズを自動的に次の適切な大きさに調整します。
シャドウ ページング
MicroKernel エンジンは、シャドウ ページングを使用して、システム障害が発生した場合に 6.0 以降のファイルが破壊されないようにします。クライアントがトランザクションの内部または外部のページの変更を要求すると、MicroKernel エンジンはデータ ファイル自体の空いた未使用の物理位置を選択し、シャドウ ページと呼ぶ新しいページ イメージをこの新しい場所に書き込みます。1 回の MicroKernel エンジンの操作で、MicroKernel エンジンは元の論理ページとすべて同じサイズの複数のシャドウ ページを作成することがあります。
変更がコミットされる、つまり、オペレーションが終了するかトランザクションが終了すると、MicroKernel エンジンはシャドウ ページを現在のページにし、元のページが再利用可能になります。MicroKernel エンジンは、有効な再利用可能ページをトラッキングするために、ページ アロケーション テーブルというマップをファイルに格納します。変更がコミットされる前にシステム障害が発生した場合、MicroKernel エンジンは PAT を更新しないため、シャドウ ページを削除し、まだ元の状態のままになっている現在のページを復帰させて使用します。
メモ:この説明では、シャドウ ページング プロセスを単純化しています。パフォーマンスの向上のため、MicroKernel エンジンは各オペレーションやユーザー トランザクションを個々にコミットせず、それらをシステム トランザクションと呼ぶまとまりにグループ化します。
クライアントがトランザクション内で動作している場合、元の論理ページに対応するシャドウ ページはそのクライアントにしか見えません。ほかのクライアントが同じ論理ページにアクセスしなければならない場合、元の(未変更の)ページが表示されます。つまり、ほかのクライアントには、最初のクライアントがまだコミットしていない変更は表示されません。元のファイルは常に有効でありかつ内部一貫性があるので、シャドウ ページングにより信頼性は向上します。
ファイルのバックアップ
定期的にファイルをバックアップすることは、データを保護する上で大切なステップです。
ファイルのバックアップの詳細については、『
Advanced Operations Guide』の
ログ、バックアップおよび復元を参照してください。
イベント ロギング
イベント ロギングは Zen の機能の 1 つで、MicroKernel エンジン、SQL インターフェイス、およびユーティリティ コンポーネントからの情報メッセージ、警告メッセージ、エラー メッセージを格納するために使用します。
詳細については、『
Advanced Operations Guide』の
メッセージ ログの見直しを参照してください。
パフォーマンスの向上
MicroKernel エンジンには、パフォーマンスを向上させる以下の機能があります。
システム トランザクション
パフォーマンスを向上し、データの回復を支援するために、MicroKernel エンジンは 1 つまたは複数のコミットされたオペレーション(トランザクションと非トランザクションの両方)をシステム トランザクションと呼ぶオペレーションのまとまりに入れます。MicroKernel エンジンは、ファイルごとにシステム トランザクションを作成します。システム トランザクションには、同じエンジンで動作する 1 つまたは複数のクライアントからのオペレーションとユーザー トランザクションを含めることができます。
メモ:システム トランザクションと、排他または並行トランザクションを混同しないでください。本書では、「トランザクション」という用語は排他トランザクションまたは並行トランザクション(ユーザー トランザクションとも呼びます)を指しています。ユーザー トランザクションはキャッシュ内のページに変更を加える方法に影響を与えるのに対して、システム トランザクションはキャッシュ内のダーティページをディスク上のファイルの一部にする方法に影響を与えます。MicroKernel エンジンは、システム トランザクションの起動とプロセスを制御します。
ユーザー トランザクションとシステム トランザクションはともにアトミック トランザクションです。つまり、これらのトランザクションは、すべての変更が行われるか、または変更が何も行われないといった具合に発生します。システム障害が発生すると、MicroKernel エンジンは障害の起きたシステム トランザクションに関連するすべてのファイルを再度開くときにそれらのファイルを回復します。障害の起きたシステム トランザクションに対して行われたすべての変更、つまり、終了した最後のシステム トランザクション以降にそのエンジン上のすべてのクライアントによって行われたファイルに対するすべてのオペレーションは失われます。ただし、ファイルは矛盾のない状態に復元されるので、システム障害の原因を解決した後にオペレーションを再試行することができます。
Zen は、アクセラレイティド モードで開いたファイルを除くすべてのログ記録可能なファイルのトランザクション一貫性保持を保証します。(ファイルに少なくとも 1 つの重複のない重複不能キーが含まれている場合は、そのファイルをログに記録することができます。キーはシステム定義とすることができます。)トランザクション一貫性保持は、MicroKernel エンジンが End Transaction に対し正常終了のステータス コードをクライアントに返す前にトランザクション ログへの書き込みを終了することを保証する機能です。アクセラレイティド モードでファイルを開くと、MicroKernel エンジンはファイルをログに記録しません。したがって、MicroKernel エンジンはファイルにエントリを記録しません。したがって、MicroKernel エンジンはそのファイルのトランザクション一貫性保持を保証できません。
MicroKernel エンジンはファイルのシステム トランザクションをロールバックした後、次にファイルを開くときにログを再生します。これにより、システム トランザクションのロールバックによって、ログには格納されているがファイルに書き込まれていないコミット済みのオペレーションが復元されます。
各システム トランザクションは 2 つの段階、つまり、準備と書き込みから構成されています。
準備段階
準備段階では、MicroKernel エンジンは現在のシステム トランザクションですべてのオペレーションを実行しますが、ファイルにページを書き込みません。MicroKernel エンジンは必要に応じてキャッシュに登録されていないページをファイルから読み取り、キャッシュにだけ新しいページ イメージを作成します。
以下のアクションはどれも準備段階の終了を引き起こし、書き込み段階の開始を示します。
•MicroKernel エンジンがオペレーション バンドル制限に達した。
•MicroKernel エンジンが起動時間制限に達した。
•キャッシュ ページの合計数に対する書き込み準備されたページの比率がシステムのしきい値に達した。
メモ:一般に、準備段階は MicroKernel エンジン オペレーションの完了後に終了します。しかし、ユーザー トランザクションが完了する前に時間制限またはキャッシュしきい値に達する可能性があります。MicroKernel エンジンは、いずれにしても書き込み段階に切り替わります。
書き込み段階
書き込み段階では、MicroKernel エンジンは準備段階で準備されたすべてのページをディスクに書き込みます。MicroKernel はまず、すべてのデータ ページ、インデックス ページおよび可変ページを書き込みます。これらのページは実際にはシャドウ ページです。これらのページが書き込まれている間、ディスク上のファイルの一貫性は変わりません。
しかし、PAT ページは現在のページとしてシャドウ ページを指示するため、システム トランザクションの重要部分は PAT ページが書き込まれている間に発生します。この段階を保護するために、MicroKernel エンジンは FCR にフラグを書き込みます。すべての PAT ページが書き込まれると、最後の FCR が書き込まれるため、ファイルは一貫性を保ちます。この段階でシステム障害が発生すると、次にファイルが開かれたときに MicroKernel エンジンはシステム障害を認識し、ファイルを直前の状態にロールバックします。次に、トランザクション ログ ファイル内の一貫性保持可能なユーザー トランザクションはすべてファイルに書き込まれます。
システム トランザクションの頻度
頻度が低い
システム トランザクションの頻度を低くすると、ほとんどの構成ではパフォーマンスが向上します。その中には、ファイルが排他的に開かれる、クライアント/サーバー、シングル エンジン ワークステーションおよびマルチエンジン ワークステーション環境があります。
MicroKernel エンジンがシステム トランザクションの起動回数を少なくすると、ダーティページ、つまり、書き込みが必要なページはメモリ内に長く存在します。アプリケーションが多数の変更操作を行っている場合、これらのページはディスクに書き込まれる前に何回も更新される可能性があります。つまり、ディスクの書き込みが少なくなります。実際に、最も効率の良いエンジンは必要なときだけ書き込まれるエンジンです。
到達するとシステム トランザクションが起動される制限には、オペレーション バンドル制限、起動時間制限、キャッシュ サイズの 3 つがあります。これらの制限に達すると、MicroKernel エンジンはシステム トランザクションを起動します。この設定の詳細については、『Advanced Operations Guide』を参照してください。
システム トランザクションの回数を減らす最も良い方法は、オペレーション バンドル制限と起動時間制限をさらに高い値に設定する方法です。キャッシュのサイズを増やすこともできます。
頻度が高い
MicroKernel エンジンがシステム トランザクションを実行する回数を少なくすることの欠点は、ディスクに書き込まなければならないマシン メモリ内のデータが常に多くなるという点です。停電などのシステム障害が発生すると、失われるデータが多くなります。MicroKernel エンジンはファイルを一貫性のある使用可能な状態に保つようにつくられていますが、その状態には最新の変更が含まれていない場合があります。もちろん、トランザクション一貫性保持でユーザー トランザクションを使用すると、このリスクが最も少なくなります。パフォーマンスの向上に対してシステム トランザクションの回数を減らすことのリスクをよく考慮してください。
たとえば、アプリケーションがワークステーション エンジンを使用し、低速または信頼性の低いネットワーク接続を通じてリモート ファイルを更新している場合、変更データができるだけ早くディスクに書き込まれるようにシステム トランザクションを頻繁に実行する必要があります。
メモリ管理
キャッシュは、読み取るページをバッファーするために MicroKernel エンジンが予約するメモリ領域です。アプリケーションがレコードを要求すると、MicroKernel エンジンはまず、そのレコードを含むページが既にメモリ内にあるかどうかを確認するためにキャッシュを調べます。そうであれば、MicroKernel エンジンはレコードをキャッシュからアプリケーションのデータ バッファーに転送します。ページがキャッシュ内になければ、MicroKernel エンジンはページをディスクからキャッシュ バッファーに読み取ってから要求されたレコードをアプリケーションに転送します。MicroKernel エンジン キャッシュはローカル クライアントにより共有され、複数のオペレーション間で使用されます。
MicroKernel エンジンが新しいページをメモリに転送しようとするときにすべてのキャッシュ バッファーがいっぱいであれば、MicroKernel エンジンがキャッシュ内のどのページを上書きするかを LRU(least-recently-used)アルゴリズムが決定します。LRU アルゴリズムは、最近参照されたページをメモリに保持することによって処理時間を短縮します。
アプリケーションがレコードを挿入または更新すると、MicroKernel エンジンはまず対応するページのシャドウ イメージを作成し、キャッシュでそのページを変更し、次にそのページをディスクに書き込みます。変更されたページは、MicroKernel エンジンが新しいページでキャッシュ内のそのページのイメージを上書きできると LRU アルゴリズムが決定するまで、キャッシュ内に残ります。
一般に、キャッシュが大きいほどパフォーマンスが向上するのは、ある時点でメモリ内に保持するページ数を多くすることができるからです。MicroKernel エンジンを使用して、I/O キャッシュ バッファーに予約するメモリ量を指定することができます。メモリ量を決定する場合は、アプリケーションの必要メモリ量、コンピューターにインストールされた総メモリ量、および、すべての並行 Zen アプリケーションがアクセスする全ファイルの結合サイズを考慮してください。このキャッシュの設定は、[キャッシュ割当サイズ]で行います。
Zen V8 以降のリリースでは、2 番目の動的 L2 キャッシュも使用できます。この動的キャッシュの設定は、[MicroKernel エンジンの最大メモリ使用量](v9.1 以降では[MicroKernel の最大メモリ使用量])で行います。これらの設定の詳細については、『Advanced Operations Guide』を参照してください。
メモ:使用可能な物理メモリよりキャッシュを多くすると、実際にパフォーマンスが大きく低下する可能性があるのは、仮想メモリ内のキャッシュメモリの一部がディスク上にスワップされるからです。MicroKernel エンジン キャッシュは、オペレーティング システムがロードされた後で使用可能な物理メモリの約 60% に設定することをお勧めします。
ページ プリアロケーション
ページ プリアロケーションは、MicroKernel エンジンがディスク領域を必要とするときにそのスペースを使用できるようにします。データ ファイルがディスク上の連続する領域を占有する場合、ファイル操作を高速化することができます。速度の向上は、非常に大きなファイルで最も顕著です。この機能の詳細については、
ページ プリアロケーションを参照してください。
Extended オペレーション
Extended オペレーション-Get Next Extended(36)、Get Previous Extended(37)、Step Next Extended(38)、Step Previous Extended(39)、および Insert Extended(40)-を使用すると、パフォーマンスを大幅に向上できます。Extended オペレーションは、アプリケーションにもよりますが、MicroKernel エンジンの要求数を 100 分の 1 以下に減らすことができます。これらのオペレーションには、不要なレコードがアプリケーションに送られないように返されたレコードにフィルターをかける機能があります。この最適化手法は、ネットワークを介してデータを送受信しなければならないクライアント/サーバー環境で最も良い結果をもたらします。
これらのオペレーションの詳細については、
マルチレコードのオペレーションを参照してください。
ディスク使用量
MicroKernel エンジンには、必要なディスク使用量を最小限にするための以下の機能があります。
空きスペース リスト
レコードを削除すると、そのレコードがこれまで占有したディスク領域が空きスペース リストに設定されます。新しいレコードを挿入すると、MicroKernel エンジンは新しい可変ページを作成する前に空きスペース リスト上のページを使用します。空きスペース スレッショルドは、ページが空きスペース リストに表示されるには、可変ページにどれだけの空きスペースが残っている必要があるかを MicroKernel エンジンに示します。
このような空き領域を再利用する方法では、ディスク領域を再利用するようにファイルを再編成する必要がありません。また、空きスペース リストを使用すると、数ページにまたがる可変長レコードの断片化を抑えることができます。空きスペース スレッショルドを高く設定すると断片化を減らすことができますが、ファイルのためのディスク領域がより多く必要になります。
インデックス バランスの実行
インデックス ページがいっぱいになると、MicroKernel エンジンはデフォルトで新しいインデックス ページを自動的に作成し、いくつかの値をいっぱいになったインデックス ページから新しいインデックス ページへ移動します。[インデックス バランスの実行]オプションをオンにすると、既存のインデックス ページがいっぱいになるたびに新しいインデックス ページを作成しないようにすることができます。インデックス バランスを使用すると、MicroKernel エンジンはインデックス ページがいっぱいになるたびに、兄弟インデックス ページ内で利用可能な領域を探します。MicroKernel エンジンは次に、いっぱいになったインデックス ページから空き領域のあるインデックス ページへ値を振り分けます。
インデックス バランスは、インデックス ページの使用度を高めることにより、ページ数を減らし、同レベルのノード間でキーを均等に分配するため、読み取り操作でのパフォーマンスが向上します。しかし、この機能を使用すると、MicroKernel エンジンはより多くのインデックス ページを調べるために余分な時間が必要になったり、書き込み操作でより多くのディスク I/O が必要になったりする可能性もあります。インデックス バランスの正確な影響は状況によって異なりますが、インデックス バランスを使用した場合、書き込み操作のパフォーマンスは概して約 5 ~ 10% 低下します。
インデックス バランスは「定常状態」のファイルのパフォーマンスに影響を与えます。普通の変更操作は多少遅くなりますが、普通の取得操作は速くなります。平均的なインデックス ページにより多くのキーを収容することによって、これを行います。通常のインデックス ページは 50 ~ 65% まで満たされ、この場合、インデックス バランスされたページは 65 ~ 75% まで満たされます。つまり、検索するインデックス ページが少なくなります。
Create Index(31)でインデックスを作成すると、インデックス ページは 100% フルに近くなるため、これらのファイルが書き込みでなく読み取りについて最適化されます。
メモ:ファイル内の File Flag フィールドに Index Balanced File ビットを設定する方法で、ファイル単位でインデックス バランスを指定することもできます。
[インデックス バランスの実行]オプションを有効にすると、アプリケーションが設定したバランス ファイル フラグの指定とは無関係に、MicroKernel エンジンはすべてのファイルでインデックス バランスを行います。インデックス バランス設定オプションの指定方法については、『Zen User's Guide』を参照してください。
データ圧縮
MicroKernel エンジンはデータ圧縮を使用して、ファイルのレコードを挿入または更新する前にそれらのレコードを圧縮し、それらのレコードを取得するときにレコードを解凍します。圧縮されたレコードの最終の長さはそのレコードがファイルに書き込まれるまで決定できないので、MicroKernel エンジンは常に圧縮されたファイルを可変長レコード ファイルとして指定します。ただし、固定長ファイルでデータ圧縮を使用すると、MicroKernel エンジンは挿入操作や更新操作で、データ ファイルに指定された固定レコード長より長いレコードを生成できないようにします。
MicroKernel エンジンは圧縮されたレコードを可変長レコードとして格納するため(可変長レコードを許可しないようにファイルを作成した場合でも)、頻繁な挿入、更新、および削除を行う場合は、個々のレコードがいくつかのデータ ページにわたって断片化される場合があります。この断片化により、MicroKernel エンジンは 1 つのレコードを取得するために複数のファイル ページの読み取りが必要になる可能性があることから、アクセス時間が遅くなるおそれがあります。しかし、データ圧縮により、多数の繰り返し文字を含むレコードを格納する場合に必要となるディスク容量を、大幅に削減することもできます。MicroKernel エンジンは、5 つ以上の同じ連続文字を 5 バイトに圧縮します。
この機能の詳細については、
レコード圧縮を参照してください。
ブランク トランケーション
ブランク トランケーションはディスク容量を節約します。可変長のレコードを許し、かつデータ圧縮機能を使用しないファイルにのみ適用できます。この機能の詳細については、
ブランク トランケーションを参照してください。