トランザクショナル インターフェイスの基礎
この章では、Pervasive PSQL のトランザクショナル インターフェイスの機能について、以下の各セクションで説明します。
トランザクショナル インターフェイスの概要
Btrieve API は、トランザクショナル データベース エンジンの低レベル インターフェイスで、データベース設計の機能面を具現するものですが、SQL、Java、ODBC などの高レベル インターフェイスには透過的です。たとえば、SQL インターフェイスはデータが物理的にどのように格納されるかに関係なく動作します。しかし、トランザクショナル インターフェイスの開発者はページ サイズ、物理および論理カレンシー、型検査、妥当性検査などの低レベルの側面を考慮する必要があります。これらの低レベルの側面を考慮しても、Btrieve API には優れた柔軟性とデータに対する制御性があります。
トランザクショナル データベース エンジンは情報をファイルに格納します。このファイルのサイズは Pervasive PSQL バージョン 9.5 以降では最大 256 GB です(バージョン 9.5 までの 9.x は 128 GB で、それ以前のバージョンでは 64 GB です)。各データ ファイル内には、データ バイトを収容するレコードがあります。1 つのファイルに最大 40 億個のレコードを収容できます。
レコード内のデータは、社員の名前、ID、住所、電話番号、賃率などを表します。しかし、トランザクショナル データベース エンジンはレコードを単なるバイトの集合として解釈します。つまり、レコード内で論理的に区別されている情報を認識しません。トランザクショナル データベース エンジンにおいては、ラスト ネーム、ファースト ネーム、社員 ID などはレコード内に存在しません。
トランザクショナル インターフェイスがレコード内で認識できる唯一の区別されている情報の部分は、キーです。キーは、レコードに対する高速な直接アクセスと、キー値によるレコードのソート手段を提供します。トランザクショナル インターフェイスには各ファイル内のレコードの構造を理解する方法がないため、以下の項目を識別することによって各キーを定義します。
•番号。これは、キーのリスト内のキーの順序です。バージョン 6.0 以降のファイルでは、キー番号間にギャップをとることができます。つまり、トランザクショナル データベース エンジンは連続番号の付いたキーを必要としません。キーを追加する場合、キー番号を指定したり、トランザクショナル インターフェイスに使用可能な最小キー番号を割り当てさせることができます。キーを削除する場合、残りのキー番号をそのままにしたり、トランザクショナル インターフェイスに連続番号を付け直させることができます。
•位置。これは、キーのレコードの先頭からのオフセットです。
•長さ。これは、キーに使用するバイト数です。
•型。これは、キーのデータ型です。
•属性。これは、トランザクショナル インターフェイスにキー値を処理させる方法に関する追加情報を示します。トランザクショナル インターフェイスは、セグメント、重複可能、変更可能、ソート順、大文字と小文字の区別、オルタネート コレーティング シーケンス、ヌル値などのキー属性をサポートします。
キーはいつでも作成または削除することができます。トランザクショナル インターフェイスは、データ ファイルで定義されたキーごとにインデックスを作成します。インデックスは、データ ファイル自体の内部に格納されます。インデックスは、ファイル内の各キー値を実際のデータ内のオフセットへマップします。通常は、トランザクショナル インターフェイスがデータのアクセスまたはソートを行う場合、ファイル内のすべてのレコードを検索しません。その代わり、インデックスを検索し、その後要求に合うレコードだけを処理します。
インデックスは、データ ファイルの作成時、またはそれ以降いつでも作成できます。データ ファイルを作成するときは、トランザクショナル インターフェイスがインデックスの作成に使用するキーを 1 つまたは複数定義できます。
ファイルを作成した後に、外部インデックスを定義することもできます。外部インデックス ファイルは、指定するキーでソートされたレコードを含む標準データ ファイルです。各レコードは、以下の項目から成ります。
•元のデータ ファイルにおけるレコードの物理位置を識別する 4 バイト アドレス
•キー値
いつインデックスを作成するかに関係なく、ポジショニングの規則(どのレコードが現在のレコードで、どのレコードが次レコードかなどを管理するガイドライン)は同じです。
ファイルを作成すると同時にインデックスを作成する場合、トランザクショナル インターフェイスはレコードがファイルに挿入された年代順に重複キー値を格納します。既に存在するファイルのインデックスを作成する場合、トランザクショナル インターフェイスは、インデックス作成時の対応するレコードの物理順で重複キー値を格納します。トランザクショナル インターフェイスがインデックスに重複キー値を格納する方法は、キーがリンク重複か繰り返し重複かによっても異なります。詳細については、
重複可能性を参照してください。
メモ: レコードの年代順は、レコードを更新してそのキー値を変更する場合、インデックスを削除して作成し直す場合、またはファイルを作成し直す場合に変化する可能性があります。したがって、ファイル内のレコードの順序がレコードの挿入された順序を常に反映するとは考えないでください。レコード挿入順序をトラッキングする場合は、AUTOINCREMENT キーを使用してください。
アプリケーションでインデックスが不要になれば、インデックスを削除できます。データ ページやその他のインデックス ページに対して、インデックスがファイル内で使用した領域が解放されます。(ただし、この空き領域はファイルに割り当てられたままになります。インデックスを削除した後に物理的なファイル サイズは減少しません。)
キーの定義に関する具体的な情報については、第
5 章
データベースの設計を参照してください。
トランザクショナル インターフェイス環境
エンド ユーザーがトランザクショナル インターフェイス アプリケーションを実行する前に、エンド ユーザーのコンピューターでトランザクショナル データベース エンジンのバージョンを使用できるようにする必要があります。アプリケーションに不可欠なトランザクショナル インターフェイス ソフトウェア バージョンと環境設定に関する情報をエンド ユーザーに提供する必要があります。
設定に関する注記
エンド ユーザーは、トランザクショナル インターフェイス アプリケーションについて以下の情報を知っておく必要があります。この情報をトランザクショナル インターフェイス アプリケーションに添付するドキュメントに記載してください。
•アプリケーションに必要なメモリ容量。
アプリケーションには、トランザクショナル インターフェイス自体で必要な容量より多いメモリまたはディスク領域が必要となる場合があります。アプリケーションのディスク領域とメモリ必要量を確定し、この情報をユーザーに伝えてください。トランザクショナル インターフェイスのシステム要件については、『Getting Started with Pervasive PSQL』および弊社の Web サイトを参照してください。
•アプリケーションにデフォルト以外のトランザクショナル データベース エンジン構成の設定が必要かどうか。特に、エンド ユーザーがこれらのトランザクショナル データベース エンジン オプションを変更する必要があるかどうかを考慮してください。
•作成ファイルのバージョン。アプリケーションにはトランザクショナル データベース エンジンの旧バージョンとの後方互換性が必要ですか?そうであれば、このオプションに対応する値を設定するようにエンド ユーザーに指示してください。
•インデックス バランス。アプリケーションは、作成するすべてのファイルにインデックス バランス ファイル属性を設定しますか?そうであれば、エンド ユーザーはインデックス バランスをデフォルトのオフにして使用できます。そうでなければ、MicroKernel レベルでインデックス バランスをオンにするようにエンド ユーザーに指示する必要があります。詳細については、
インデックス バランスを参照してください。
•システム データ。データベース内のすべてのファイルは重複のないキーを持っていますか?そうであれば、これらのファイルはトランザクション一貫性保守の機能を利用できます。そうでなければ、エンド ユーザーはファイルをトランザクション一貫保守性のあるものにするために[システム データの作成]を[必要な場合]または[常時]に設定しなければならない場合があります。
設定オプションの説明については、『Advanced Operations Guide』を参照してください。
ページ
ここでは、ページとトランザクショナル インターフェイスによるページの処理方法に関する以下の情報を示します。
ページ タイプ
ファイルは、一連のページから構成されています。ページとは、データベースがメモリとディスクの間で転送する記憶容量の単位です。ファイルは、以下のページ タイプから構成されています。
ファイル コントロール レコード (FCR) | ファイルのファイル サイズ、ページ サイズ、その他の特性などのファイルに関する情報が含まれています。6.0 以降のすべてのデータ ファイル内の最初の 2 つのページは FCR ページです。トランザクショナル データベース エンジンは常に、FCR ページのうちの 1 ページを現在のページと見なします。現在の FCR ページには、最新のファイル情報が含まれています。 |
ページ アロケーション テーブル(PAT) | ファイル内のページを追跡するために使用されるトランザクショナル データベース エンジンの内部的な実装の一部。 |
データ | レコードの固定長部分が含まれています。トランザクショナル データベース エンジンは、1 つの固定長レコードを 2 つのデータ ページにまたがって分割しません。ファイルが可変長レコードを許可していないか、データ圧縮を使用しない場合、ファイルにはデータ ページはありますが可変ページはありません。 |
可変 | レコードの可変長部分が含まれています。レコードの可変長部分が可変ページの残りの領域より長い場合、トランザクショナル データベース エンジンは複数の可変ページにわたって可変長部分を分割します。ファイルが可変長レコードを許可しているか、データ圧縮を使用する場合、ファイルにはデータ ページと可変ページの両方があります。 |
インデックス | レコードの検索で使用されるキー値が含まれています。 |
オルタネート コレーティング シーケンス(ACS) | ファイル内のキーのオルタネート コレーティング シーケンスが含まれています。 |
6.0 以降のすべてのファイルには、FCR ページと PAT ページがあります。
標準ファイルにはデータ ページとインデックス ページも含まれており、オプションとして可変ページと ACS ページが含まれています。
データオンリー ファイルにはインデックス ページが含まれていません。
キーオンリー ファイルにはデータ ページが含まれていません
ページ サイズ
ファイルを作成するときに固定ページ サイズを指定します。指定できるページ サイズやファイル オーバー ヘッドなどは、ファイル形式をはじめさまざまな要因によって異なります。ページ サイズの説明については、第
5 章
データベースの設計を参照してください。以下のセクションでは概要について説明します。
ページ サイズの基準
指定するページ サイズは、以下の基準を満たす必要があります。
•ファイルのレコード長に相応なデータ ページを使用可能にする。
各データ ページには、一定のバイト数のオーバーヘッド情報が含まれています。表
19 を参照してください。その後、トランザクショナル データベース エンジンは各データ ページにできるだけ多くのレコードを格納しますが、ページにまたがってレコードの固定長部分を分割することはありません。
最適なページ サイズでは、各データ ページの残余スペース量をできるだけ少なくしながら、最も多いレコードを収容できます。ページ サイズが大きいほど、通常はディスク領域の使用効率が高くなります。内部レコード長(ユーザー データ + レコード オーバーヘッド)が小さく、ページ サイズが大きいと、無駄な領域がかなりの量になる可能性があります。
•ファイルのキー定義に適合するインデックス ページを許可する。
各インデックス ページには、一定のバイト数のオーバーヘッド情報が含まれています。表
19 を参照してください。その後、ファイルのインデックス ページは 8 個のキーと各キーのオーバーヘッド情報を収容できる大きさがなければなりません(設定ごとのオーバーヘッドのバイト数の説明については、表
17、
18、
19、
20 および
21 を参照してください)。
•ファイルが必要とするキー セグメント数を許可する。
セグメント化で説明したように、ファイルに対して定義するページ サイズはそのファイルに対して指定できるキー セグメント数を制限します。
•パフォーマンスを最適化する。
パフォーマンスを最適化するには、ページ サイズを 2 のべき乗のサイズ、つまり、512 バイト、1,024 バイト、2,048 バイト、4,096 バイト、8,192 バイト、16,384 バイトに設定します。トランザクショナル データベース エンジンの内部キャッシュは一度に複数のサイズのページを格納できますが、2 のべき乗単位に分割されます。ページ サイズ 1,536、2,560、3,072 および 3,584 では、実際に、トランザクショナル データベース エンジン キャッシュ内のメモリが無駄になります。2 のべき乗のページ サイズを使用すると、キャッシュの使用効率が良くなります。
大きなページ サイズと小さなページ サイズ
現代のオペレーティング システムを最も効率よく使用するには、より大きなページ サイズを選択する必要があります。DOS が傑出したオペレーティング システムであった時代、つまり、セクターが 512 バイトで、すべての I/O が 512 の倍数で発生していたときは、小さなページ サイズが使用されていました。現在はそうではありません。32 ビットおよび 64 ビットのオペレーティング システムでは、いずれもデータを 4,096 バイトあるいはそれ以上のブロック単位でキャッシュに移動させます。CD ROM ドライブは、2,048 バイト単位で読み取られます。
トランザクショナル インターフェイスのインデックスは、4,096 バイトあるいはそれ以上のページ サイズを使用する場合に最も効率が良くなります。キーはノードごとにさらに多くの分岐を持つため、正しいレコード アドレスを検索するための読み取りは少なくて済みます。このことは、アプリケーションがキーでランダムな読み取りを行っている場合に重要です。アプリケーションがキーまたはレコードでファイルに順次アクセスする場合は重要ではありません。
ページを小さくするもっともな理由は、競合を避けるためです。各ページのレコード数が少ないほど、さまざまなエンジンまたはトランザクションが同時に同じページを要求する可能性は低くなります。ファイルのレコード数が比較的少なく、レコードが小さい場合は、小さなページ サイズを選択できます。ファイルが大きいほど、競合の発生する可能性が低くなるようです。
大きなページ サイズのもう 1 つの潜在的な問題は、バージョン 7.0 以降のファイルに特有なものです。同じデータ ページに収容できるレコードまたは可変長セクションの数は最大 256 個です。短いレコード、圧縮されたレコード、または短い可変長セクションがある場合は、すべてのページにまだ数百バイト残っていても、すぐに制限に達する可能性があります。その結果、必要とされるよりもはるかに大きなファイルになります。レコード サイズがわかれば、このことがどの程度大きな問題かを計算できます。
ページ サイズの決定時に考慮する要素
•キーはページ サイズが大きいほど効率よく働きます。B ツリーのノードごとにより多くの分岐ができるため、B ツリーのレベルが少なくなります。レベルが少ないとは、ディスクの読み込みや書き込みが少ないことです。ディスク読み込みが少ないと、パフォーマンスは向上します。
•並行処理は、クライアント トランザクションが使用されている場合は特に、より小さなページの方が効率が良くなります。トランザクション時、トランザクショナル データベース エンジンは変更されるページをロックするので、ほかのすべてのクライアントは、トランザクションが終了または中止するまで、ロックされたページが解除されるのを待つ必要があります。たくさんのクライアントが並行して同一ページにアクセスを試みる場合、各ページで見つけられるデータが少ないほど効率が良くなります。
•ページへのランダム アクセスは、より小さなサイズのページの方が効率が良くなります。これは、実際に使用するデータがキャッシュにあることが多いためです。再度データにアクセスした場合、十中八九まだキャッシュ内にあるでしょう。
•大量のレコードにシーケンシャル アクセスする場合は、大きなサイズのページの方が一度により多くのレコードを読み取れるため、効率が良くなります。ページを読み取るたびにほとんどすべてを使用するので、確実に読み取り回数が少なくなります。
データベース設計者はこれらの相反するニーズの中から選択しなければなりません。参照テーブルはめったに変更されませんが、ほとんど常に検索またはスキャンされるため、大きなページ サイズにする必要があります。トランザクション内で頻繁に追加および更新されるトランザクション ファイルは、小さいページ サイズにする必要があります。
メモ: これらの必要性のバランスをとる必要があります。
すべての要因を慎重に検討することによって、どのようなページ サイズにするのかに対する正しい答えを導くことができます。ページ サイズの選択の詳細については、
ページ サイズの選択を参照してください。
ファイル タイプ
Btrieve API は、Pervasive PSQL 9.5 以降のデータ ファイルでは最大ファイル サイズ 256 GB(9.x から 9.5 までのバージョンでは 128 GB、それ以前のバージョンでは 64 GB)をサポートし、長いファイル名、および 3 つのデータ ファイル タイプをサポートしています。
メモ: Btrieve 6.x およびそれ以前のユーザーのために、Pervasive PSQL はファイルを 8.x および 7.x 形式で作成することができます。これらの新しい形式により、拡張性と新機能がもたらされました。
Btrieve 6.x およびそれ以前のバージョンは、Pervasive PSQL 7.x または 8.x ファイルを開けません。しかし、Pervasive PSQL v11 SP3 はバージョン 7.0 より前のファイルを開くことができます。Pervasive PSQL v11 SP3 はバージョン 7.0 より前のファイルを開く際、ファイルを 7.0 または 8.0 の形式に変換しません。また、バージョン 8.0 より前の形式でファイルを作成するように Pervasive PSQL を設定することもできます。これは、新しく作成された V8 より前のファイルを使用する場合に役立ちます。
標準データ ファイル
標準 7.x 以降のファイルには、FCR の 2 ページに続けて多数の PAT ページ、インデックス ページ、データ ページがあり、ファイルによっては可変ページや ACS ページもあります。固定長レコードまたは可変長レコードで使用する標準ファイルを作成できます。標準ファイルにはすべてのインデックス構造とデータ レコードが含まれているので、トランザクショナル インターフェイスはファイル内のレコードに関するすべてのインデックス情報を動的に保守できます。
データオンリー ファイル
データオンリー ファイルを作成する場合には、キー情報を何も指定しないので、Pervasive PSQL はファイルのインデックス ページを割り当てません。このため、初期のファイル サイズは標準ファイルの場合より小さくなります。データオンリー ファイルを作成後、ファイルにキーを追加できます。
キーオンリー ファイル
キーオンリー ファイルには、FCR ページに続けて多数の PAT ページとインデックス ページだけが含まれています。(また、ファイルに参照整合性制約を定義した場合は、1 ページ以上の可変ページが含まれます。)
キーオンリー ファイルはキーを 1 つだけ含み、レコード全体がそのキーと共に格納されるため、データ ページは不要です。キーオンリー ファイルは、レコードに単一のキーが含まれており、かつそのキーが各レコードの大部分を占有している場合に有効です。キーオンリー ファイルのもう 1 つの一般的な用途は、標準データ ファイルの外部インデックスとして使用する場合です。
キーオンリー ファイルには以下の制限が適用されます。
•各ファイルには 1 つのキーしか含められません。
•定義できる最大レコード長は 253 バイト(バージョン 6.0 より前は 255 バイト)です。
•キーオンリー ファイルではデータ圧縮を行えません。
ラージ ファイル
トランザクショナル インターフェイスは、Pervasive PSQL 9.5 以降では最大 256 GB(9.x から 9.5 までのバージョンでは 128 GB、それ以前のバージョンでは 64 GB)までのファイル サイズをサポートしています。ただし、多くのオペレーティング システムでは、単一のファイルでこれだけの大きなサイズをサポートしていません。オペレーティング システムのファイル サイズの制限より大きいファイルをサポートするために、トランザクショナル インターフェイスは大きなファイルをオペレーティング システムでサポートできるさらに小さなファイルに分割します。大きな論理ファイルは、拡張ファイルと呼びます。拡張ファイルを構成するさらに小さい物理ファイルは、エクステンション ファイルと呼びます。ベース ファイルは、大きすぎて 1 つの物理ファイルとしてサポートできなくなった元のデータ ファイルです。非拡張(非セグメント化)ファイルは、より効率的な I/O を提供するので、パフォーマンスが向上します。
Pervasive PSQL 9.x 以降のファイルが自動的に 2 GB ごとに
拡張されないようにすることができます。セグメント操作の設定を変更するには、『
Advanced Operations Guide』の
PCC による設定に記述されているように、PCC(Pervasive PSQL Control Center)の設定プロパティにアクセスします。ここで[
セグメント サイズを 2 GB に制限]オプションを設定することができます。
このオプションが選択されていない場合、Pervasive PSQL 9.x 以降のファイルが自動的に 2 GB にセグメント化されることはありません。バージョン 8.x およびそれ以前のデータ ファイルは、引き続き 2 GB に到達するごとに拡張されます。ファイルが既に拡張されている場合は、セグメント化されたままです。
設定プロパティに関わらず、すべてのファイルは現在のオペレーティング システムのファイル サイズ制限に基づいて引き続き拡張されます。
拡張ファイルなどのファイルのバックアップについては、
ファイルのバックアップを参照してください。
長いファイル名
トランザクショナル インターフェイスは 255 バイト以下の長いファイル名をサポートします。以下の項目もこの上限に従います。
•ローカライズされたマルチバイトまたはシングル バイト バージョンの文字列。
•リクエスターによって作成された UTF-8 UNICODE 形式の UNC バージョンのファイル名。
[スペースを含むファイル/ディレクトリ名]クライアント設定オプションが有効になっていない場合、ファイル名にスペースを含めることはできません。デフォルト設定は、
オンです。『
Advanced Operations Guide』の
長いファイル名と埋め込みスペースのサポートを参照してください。
ラージ ファイルを使用する場合やアーカイブ ロギングまたは Continuous オペレーションの実行中など、トランザクショナル インターフェイスが既存のファイル名に基づいて新しいファイルを作成する場合は(『
Advanced Operations Guide』の第
8 章
ログ、バックアップおよび復元を参照)、以下の例に示すように、新しいファイル名には元のファイル名のできるだけ多くの部分を含み、特有のファイル拡張子を使用します。
元のファイル名 | 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 を除くすべてのデータ型を使用してキーを定義できます。
6.x より前の形式を使用している場合、NUMERICSA および NUMERICSTS はデータ型やキー タイプとして使用できません。
データ型の詳細については、『
SQL Engine Reference』の
データ型を参照してください。
キー属性
以下のセクションでは、キーを定義するときに指定できる属性について説明します。
キー属性の解説
このセクションでは、キーに割り当てられる以下の属性について説明します。
セグメント化
キーは、各レコード内の 1 つ以上のセグメントから構成できます。レコード内の任意の連続バイトをセグメントとすることができます。キー タイプとソート順序は、キー内のセグメントごとに変えることができます。
使用できるインデックス セグメントの数はファイルのページ サイズによって異なります。
ページ サイズ(バイト数) | キー セグメントの最大数(ファイル バージョン別) |
8.x 以前 | 9.0 | 9.5 |
512 | 8 | 8 | 切り上げ2 |
1,024 | 23 | 23 | 97 |
1,536 | 24 | 24 | 切り上げ2 |
2,048 | 54 | 54 | 97 |
2,560 | 54 | 54 | 切り上げ2 |
3,072 | 54 | 54 | 切り上げ2 |
3,584 | 54 | 54 | 切り上げ2 |
4,096 | 119 | 119 | 119 または 2043 |
8,192 | N/A1 | 119 | 119 または 4203 |
16,384 | N/A1 | N/A1 | 119 または 4203 |
1 N/A は「適用外」を意味します。 2 「切り上げ」は、ページ サイズを、ファイル バージョンでサポートされる次のサイズへ切り上げることを意味します。たとえば、512 は 1,024 に切り上げられ、2,560 は 4,096 に切り上げるということです。 3 リレーショナル インターフェイスで使用できるインデックス セグメントの最大数は 119 です。トランザクショナル インターフェイスの場合、最大数は、ページ サイズ 4,096 では 204、ページ サイズ 8,192 および 16,384 では 420 です。 |
インデックス セグメントとトランザクショナル インターフェイスに関する詳細については、ステータス コードの
26:指定されたキーの数が不正です。および
29:キー長が不正です。を参照してください。
キーの合計長はキー セグメントの長さの合計であり、最大長は 255 バイトです。レコード内でキー セグメントは互いに重なり合っていてもかまいません。
セグメント化されたキーが重複不能キーである場合、セグメントを組み合わせて一意の値をつくる必要がありますが、個々のセグメントには重複を含めることができます。このタイプのセグメント化されたキーを定義する場合、たとえ特定セグメントに重複がある可能性があっても、各セグメントにはキー レベル属性として duplicates=no を持ちます。特定セグメントが常に一意であるようにするには、セグメント化されたキー定義の他に個別の重複不能キーとしてそのセグメントを定義します。
トランザクショナル インターフェイス呼び出しを行う場合、キー バッファーの形式はキー番号で指定されるキーを収容できなければなりません。したがって、keynumber=0 を定義した場合、キー 0 が 4 バイト整数ならば、キー バッファー パラメーターは以下のいずれかにすることができます。
•4 バイト整数へのポインター
•最初の要素または唯一の要素が 4 バイト整数である構造体へのポインター
•4 バイト以上の文字列またはバイト配列へのポインター
基本的には、トランザクショナル インターフェイスはキー バッファーとして使用されるメモリの場所へのポインターを取得します。トランザクショナル インターフェイスはそのメモリの場所に、Get Equal などのオペレーションで指定されたキー番号に対応するデータ値があることを期待します。また、トランザクショナル インターフェイスはその場所にデータを書き込むことができ、書き込んだデータが指定されたキー番号に対応するキー値になります。このような場合は、キー値全体を収容できる十分なメモリの場所を割り当てる必要があります。
トランザクショナル インターフェイスにとって、キーは、たとえ複数のセグメントから構成されていても、単一のデータの集合です。セグメント機能を使用すれば、連続していないデータのバイトを 1 つのキーとして結合できます。また、キー データの個々の部分に異なるソート規則(サポートされるデータ型で指定されているとおり)を適用できます。一般的に、1 つのキー セグメントに関連付けられているデータ型がソート規則として使用されます。ソート規則は、2 つの値を比較してどちらの値が大きいか決定する方法をトランザクショナル インターフェイスに指示します。データ型は、データの妥当性検査に使用されません。
トランザクショナル インターフェイスは、常にキー セグメントでなくキー全体を処理します。キーを処理するには、キー全体を保持できる十分な大きさのキー バッファーを設定します。アプリケーションの中には、すべてのトランザクショナル インターフェイス呼び出しで使用する汎用の 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 を渡します。トランザクショナル インターフェイスが呼び出しを終了し、レコードが見つかった場合には、ステータス コード 0 が返され、対応するデータ レコードが返されて、キー バッファーに 3 つのセグメントすべてを含むキー値が設定されます。
重複可能性
Pervasive PSQL は重複キー値を処理する方法として、リンク(デフォルト)および繰り返しの 2 つをサポートします。リンク重複キーでは、トランザクショナル インターフェイスはインデックス ページの 1 組のポインターを使用して、同じキー値を持つレコードのうち年代順に最初と最後のレコードを識別します。さらに、トランザクショナル インターフェイスはデータ ページの各レコード内の 1 組のポインターを使用して、同じキー値を持つレコードのうち年代順に前のレコードと次のレコードを識別します。キー値は、インデックス ページにのみ 1 回格納されます。
繰り返し重複キーでは、トランザクショナル インターフェイスはインデックス ページの 1 つのポインターを使用して、データ ページの対応するレコードを識別します。キー値は、インデックス ページとデータ ページの両方に格納されます。重複キーの詳細については、
重複キーを参照してください。
変更可能性
キーを変更可能キーとして定義すると、トランザクショナル インターフェイスはレコードが挿入された後でもキーの値を変更できるようにします。キーの 1 つのセグメントが変更可能であれば、すべてのセグメントが変更可能でなければなりません。
ソート順序
デフォルトでは、トランザクショナル インターフェイスはキー値を昇順(最小の値から最大の値へ)にソートします。しかし、トランザクショナル インターフェイスがキー値を降順(最大の値から最小の値へ)に並べるように指定することができます。
メモ: トランザクショナル インターフェイスの Get オペレーション(Get Greater(8)、Get Greater or Equal(9)、Get Less Than(10)および Get Less Than or Equal(11))で降順キーを使用するときは注意してください。この場合、Greater または Less はキーに関する順序を参照するため、降順キーの場合には、この順序は対応する昇順キーの逆になります。
降順キーで Get Greater オペレーション(8)を実行する場合、トランザクショナル インターフェイスはキー バッファーで指定するキー値より小さい最初のキー値に対応するレコードを返します。たとえば、10 件のレコードと整数型の降順キーを持つファイルについて考えてみましょう。10 件のレコードの降順キーに格納されている実際の値は、整数 0、1、2、3、4、5、6、7、8、9 です。現在のレコードのキー値が 5 で Get Greater オペレーションを実行した場合、トランザクショナル インターフェイスはキー値 4 を含むレコードを返します。
同様に、降順キーで Get Less Than オペレーション(10)を実行した場合、トランザクショナル インターフェイスはキー バッファーで指定するキー値より次に大きい値を持つレコードを返します。前の例で、現在のレコードの降順キーの値が 5 で Get Less Than オペレーションを実行した場合、トランザクショナル インターフェイスはキー値 6 を含むレコードを返します。
大文字と小文字の区別
デフォルトでは、トランザクショナル インターフェイスは文字列キーをソートするときに大文字と小文字を区別します。つまり、小文字の前に大文字をソートします。キーを大文字小文字無視と定義すると、トランザクショナル インターフェイスは大文字と小文字を区別せずに値をソートします。キーにオルタネート コレーティング シーケンス(ACS)がある場合、大文字と小文字の区別は適用されません。
ヌル値
Pervasive PSQL v11 SP3 には、列のデータをヌル値として識別する方法が 2 つあります。ヌル値の元のタイプ(レガシー ヌルと呼びます)は、トランザクショナル インターフェイスで長年使用されてきました。新しいタイプのヌル識別は、真のヌルと呼びます。このセクションでは、レガシー ヌルについて簡単に説明し、次にトランザクショナル インターフェイスでの真のヌルの使用について詳細に説明します。
レガシー ヌル
ヌル値を許可するフィールドを定義する元の方法は「擬似ヌル」または「レガシー ヌル」と呼びます。これは、フィールド全体が特定のバイト値、一般的には ASCII ゼロで埋められている場合に、そのフィールドをヌルと見なすという前提に基づいています。バイト値は、インデックス作成時に指定するキー定義に指定します。トランザクショナル インターフェイスを使用する場合、トランザクショナル データベース エンジンがこの情報から行えることは、フィールドをインデックスに含めるか含めないかだけです。レガシー ヌルは、その特殊な意味にもかかわらず、その他すべての値とまったく同様にソートされる値であるため、特別なソート規則はありません。
キー定義に「全セグメント ヌル」(0x0008)のフラグが含まれている場合、キー内のすべてのセグメントがヌルと見なされると、そのキー値はインデックスに含められません。各セグメントがヌルと見なされるのは、フィールド内のすべてのバイトが「ヌル バイト」である場合です。同様に、キー定義に「一部セグメント ヌル」(0x0200)のフラグが含まれている場合、キー内の 1 つ以上のセグメントがヌルと見なされると、そのキー値はインデックスに含められません。各セグメントがヌルと見なされる規則は前と同じです。
SQL Relational Database エンジン(SRDE)は、SRDE が定義するインデックス内でこれらのフラグを使用しません。SRDE は、テーブル間の結合を作成するために、インデックスを介してテーブル内のすべてのレコードにアクセスできる必要があるため、これらのフラグは使用しません。
真のヌル インデックス
Pervasive.SQL 2000 以降では、「真のヌル」と呼ぶ新しいタイプのヌル インジケーターが導入されています。
真のヌルは、ヌルを許可する列の直前に 1 バイトのヌル インジケーター セグメント(NIS)を置くことによりトランザクショナル インターフェイスに実装されます。これは、その列がヌルかどうかを示すために通常の列幅に追加された特別なバイトです。このバイトの値がゼロであると、このインジケーターが関連付けられている列が通常の列、つまりヌルでないことを示します。このバイトがその他の値である場合は、その列の値がヌルであることを示します。
真のヌルを使用すると、レガシー ヌルとは異なり、値がゼロの整数とヌルの整数を区別することができます。これはその他の数値フィールドにもあてはまります。このような区別が必要のない場合には、長さ 0 の文字列フィールドはヌルであると判別することができます。
SRDE は、列にインデックスが定義されているかどうかにかかわらず、真のヌル列を識別し使用することができますが、基本のデータ ファイルはキーに含まれるフィールドしか識別することができません。
Create(14)または
Create Index(31)オペレーションのキー定義で、ヌル値を許可する列の前にヌル インジケーター セグメント(NIS)を追加することによって、トランザクショナル インターフェイスのキー内に真のヌル フィールドを定義することができます。真のヌル キーに関する規則については、
真のヌル キーの規則を参照してください。
トランザクショナル インターフェイスでは NIS のオフセットについての制約がありませんが、SRDE では NIS はヌル許可列の直前にあるものと見なします。このため、レコード内のフィールド構造で、NIS を使用する可能性のあるすべてのフィールドの前のバイトを NIS のための場所として空けておくことをお勧めします。こうしておくことにより、必要になった場合、これらのテーブルに SQL を介してアクセスする能力を維持することができます。
真のヌル キーの規則
この新しいキー タイプを使用するときは、次の規則に従う必要があります。
1 フィールド長は 1 である必要があります。
2 このフィールドは、インデックス内の同類のフィールドの前にある必要があります。言い換えると、複数セグメントのインデックスでは、同類のセグメントの直前に NIS が定義されている必要があります。NIS を最終セグメントまたは唯一のセグメントにすることはできません。
3 NIS の直後のフィールドは NIS の内容の影響を受けます。NIS がゼロの場合、直後のフィールドは非ヌルと見なされます。NIS がゼロ以外の場合、直後のフィールドはヌルと見なされます。
4 NIS のオフセットはその次のフィールドの直前のバイトである必要があります。これが、Pervasive PSQL リレーショナル エンジンがこれらのフィールドの配置として要求する様式です。したがって、このインデックス用のデータ辞書を作成する場合、NIS は制御するフィールドの直前にある必要があります。ただし、トランザクショナル API にはこれを必要条件とするものは何もありません。
NIS 値
ゼロ以外の値はすべて、次のセグメントがヌルであることを表すインジケーターと見なされます。デフォルトで、MKDE はゼロ以外の値の間の区別は行いません。Pervasive PSQL リレーショナル エンジンは現在、このフィールドがヌルであることを示すのに値 1 のみを使用します。ただし、異なるタイプのヌルを区別することはできます。これは、NIS に「大文字小文字無視」フラグを使用して行います。このキー フラグは通常、さまざまな文字列フィールドや文字フィールドにのみ適用可能であるため、NIS で使用した場合、DISTINCT に特別な意味を持たせるためにオーバーロードされます。つまり、異なる NIS 値は区別して扱われ、別個にソートされます。Pervasive Software は、将来の拡張のため最初の 15 の値を予約しています。アプリケーションでさまざまなタイプのヌルに特別な意味を持たせたい場合は、NIS に 16 より大きい値を使用してください。たとえば、より詳細なヌル定義は次のようになります。
•適用外
•未定
•決定不能
•検出不能
•必須(未定)
NIS に DISTINCT フラグ(大文字小文字無視)を追加した場合、これらの非ゼロ値は異なる値として別個にソートされます。
真のヌル値のソート
真のヌル フィールドの値は非決定です。言い換えると、その値は不明です。この定義によれば、どの 2 つのヌル値も互いに等しくなく、ほかのすべてのキー値とも等しくありません。それでも、トランザクショナル データベース エンジンはこれらのヌル値を 1 つにまとめる必要があり、ヌルに等しいキー値を見つけることができなければなりません。これを行うため、トランザクショナル データベース エンジンは比較の目的に合わせて、真のヌル値がそれぞれ等しいかのように解釈します。ソートしたり、インデックス内でヌル値の場所を検索したりする場合、真のヌル値は互いに等しいかのようにグループ化されます。しかし、重複のないインデックス内に値が既に存在するかどうかを判断しようとしているときは、真のヌルは互いに等しくなくなります。
NIS 内の非ゼロ値はすべて、直後のフィールドがヌルであることを示します。デフォルトの動作では、NIS 内の非ゼロ値はすべて同一値のように扱われ、ヌル許可フィールドがヌルであることを示していると解釈されます。したがって、NIS にさまざまな非ゼロ値を含み、それに続くヌル許可フィールドがさまざまな値を含むレコードを挿入した場合、これらは同一の値として解釈され、重複値の集まりとしてソートされます。
リンク重複キーと真のヌル
このセクションでは、リンク重複キーにいくつかのヌル値を挿入した結果について説明します。
リンク重複キーは、一意の値ごとに単一のキー エントリ、2 つのレコード アドレス ポインターを持ちます。レコード アドレス ポインターの 1 つは最初の重複レコード用で、もう 1 つは重複の連鎖の最後のレコード用です。各レコードには、連鎖内の前および次のレコードへのポインターから成る 8 バイトのオーバーヘッドがあります。連鎖の最後に新しい重複値が追加されるごとに、重複レコードは挿入された順に確実にリンクされます。インデックスに追加する目的では、すべてのヌル値は重複と見なされるので、1 つの連鎖に挿入順にリンクされます。各レコードが NIS および関連するヌル許可フィールドに異なるバイト値を持っていても、この連鎖内の最初と最後のレコードを指すキー エントリが 1 つだけ存在します。NIS キー セグメントが降順に定義されている場合、このキー エントリはインデックス内で先頭になります。それ以外は、末尾になります。
繰り返し重複キーと真のヌル
繰り返し重複キーは、インデックス内に現れる各レコードの実際のキー エントリを含みます。レコード自体にオーバーヘッドはなく、レコードごとにそれ自体を指すキー エントリがあります。この種のインデックス内の重複値は、それらが指す物理レコード アドレスによってソートされます。つまり、重複値の順序は予測不能で、たくさんのクライアントによって任意のレコードが挿入および削除される高度な同時使用環境では特にそうなります。
真のヌル値は重複値であるかのように解釈され、ヌル許可フィールドのバイト値ではなく、レコード アドレスによってソートされます。したがって、繰り返し重複キーを使用する場合、真のヌル値を含むレコードはまとめてグループ化されますが、その形式は一定ではありません。NIS セグメントが降順の場合、インデックスの最初に現れ、それ以外の場合は最後に現れます。
重複のないキーと真のヌル
トランザクショナル インターフェイスでは、重複フラグを 1 つも使用しないでインデックスを定義した場合、そのインデックスは重複のない値のみを持っている必要があります。しかし、真のヌル フィールドの値は決定不能であるため、重複と見なすことができません。このため、トランザクショナル データベース エンジンでは重複のないキーに複数の真のヌル値を入力できますが、Update オペレーションでそのキーに値が割り当てられたときに、キーの一意性が判断されるものとしています。ただし、これらの値をソートする目的では、トランザクショナル データベース エンジンはこれらを重複値であるかのようにまとめてグループ化します。したがって、真のヌル値を含むインデックスのセクションは繰り返し重複のインデックスと類似します。ヌルは物理レコード アドレスによってソートされ、その順序は予測できません。
変更不能キーと真のヌル
いったん変更不能キーに値を設定すると、変更することができません。しかし、真のヌル値は実際の値を持たないため、トランザクショナル インターフェイスでは、真のヌル インデックスに定義されているフィールドのうち一部またはすべてに真のヌル値を持つレコードを挿入しておき、後で Update オペレーションを使用して、これらのフィールド値をヌルから非ヌルに変更することができます。ただし、いずれかのフィールドがいったん非ヌルになったら、変更不能性が適用され、そのフィールドを再度ヌルにしてももはや変更はできません。
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 にどのような値が含まれていても、ゼロでない限り、その後のヌル許可フィールドはヌルです。SRDE は、SRDE が作成するすべての真のヌル インデックス セグメントに、現在このデフォルトの動作を使用します。
しかし、テーブルに異なるタイプのヌル値を格納する場合には、NIS セグメントのキー定義に NOCASE フラグ(0x0400)を追加することができます。これ以後、これを DISTINCT フラグと呼びます。これを行うと、トランザクショナル データベース エンジンは異なる NIS 値をそれぞれ他と区別して扱います。
別個の真のヌル セグメントは、それぞれの NIS 値によってグループに分けられます。前に述べたさまざまなタイプのインデックスを構築する際と同じ規則が適用されます。リンク重複キーは各別個の NIS 値に単一のエントリを持ち、そのタイプのヌルの繰り返しの先頭と末尾のポインターを持ちます。繰り返し重複および重複のないキーも、別個の NIS 値によってヌル レコードをグループ化します。降順キーでは、最も高い NIS 値がグループの先頭になり、ゼロ、非ヌル値へと小さい値へソートされます。昇順キーでは、非ヌル レコードが先頭で、NIS 値 1、2、のように続きます。Get オペレーションでは NIS 値に注意が払われます。NIS 値を 20 とするキー バッファーを使用して GetEQ を実行する場合、別個の真のヌル インデックス内のすべての NIS 値が 1 であると、トランザクショナル データベース エンジンは一致する値を見つけることができません。
SRDE は別個のヌル インデックスを作成する際に、現在 DISTINCT フラグを使用しています。ほかの Pervasive PSQL アクセス方法は現在使用していませんが、将来使用する予定です。このため、Pervasive では、これらのヌルのタイプに特定の意味を割り当てる必要がある場合に備え、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 のいくつかの組み合わせ
SRDE は常に、ヌル値が先頭に来る、真のヌル インデックス セグメントを作成します。各 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)のフラグも適用することができました。レコードを挿入すると、トランザクショナル データベース エンジンは NIS を使用してヌル許可フィールドがヌルかどうかを調べます。キー エントリがインデックスに含められるかどうかを決定するのにも同じ規則が使用されます。
メモ: SRDE が作成したファイルはこれらのフラグを使用しません。
したがって、これらのファイルにどこかの時点で SQL からアクセスする可能性があり、目的が「列がヌル」であるレコードを見つけることである場合は、これらのフラグを使用しないでください。SRDE はヌル レコードを検索するのにインデックスを使用しますが、インデックスから SRDE にアクセスすることはできません。
Extended オペレーションでのヌル インジケーター セグメントの使用
Extended オペレーションを使用すると、アプリケーションは、そのテーブルのために作成されたインデックスがない場合でも、そのテーブルのフィールドにアクセスすることができます。任意のソースから得られる知識によってレコードのフィールドを実行中に定義することにより、レコード内のフィールドにフィルターを適用することができます。このように、Extended オペレーションで真のヌル フィールドを定義することが可能になり、トランザクショナル データベース エンジンはこれらのフィールドをインデックスにソートするのと同じ比較規則を適用することができます。
Extended オペレーションのフィルターは、キーを定義するのと同じように定義する必要があります。NIS のためのフィルター セグメントに続けてヌル許可フィールドのフィルター セグメントを含めます。ヌル値を検索する場合で、ヌル許可フィールドの内容が問題にならない場合であっても、ヌル許可フィールドを含める必要があります。GetNextExtended がインデックス パスに対して最適化されるには、MKDE は両方のフィルター セグメントを必要とします。MKDE は、このことを確実にするため、ステータス 62 によって、NIS のためのフィルター式の次に非 NIS のフィルター セグメントがなかったことを示します。
NIS で使用できる比較演算子は、EQ または NE のみです。GT、GE、LT、および LE などのほかの比較演算子を使用すると、ステータス 62 が返されます。
不適切な形式の Extended オペレーション記述子によって発生するステータス 62 は、Pervasive イベント ログにシステム エラーを追加します。これらのシステム エラーは表
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 エンジン
真のヌルは、ヌル インジケーター キータイプを使用し、前述の規則に従うことによって SRDE に実装されます。トランザクショナル インターフェイス アプリケーションも、このキー タイプを使用してヌル可能フィールドがヌルかどうかをその内容にかかわらず識別することができます。これにより、整数とほかの数値データ型のヌルを識別し、これらのヌル可能フィールドを完全に管理することができます。
真のヌルと Extended オペレーション
Extended オペレーションで発生するステータス 62 はディスクリプターが不正であることを示します。ディスクリプターの何が間違っているのかを判断するのがむずかしい場合があります。データベース エンジンは Pervasive イベント ログに、問題を正確に判断するのに使用できる行を追加しました。イベント ログのエントリは次のようなものです。
12-12-2008 11:12:45 W3MKDE 0000053C W3dbsmgr.exe MY_COMPUTER E System Error:301.36.0 File: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)を非英数字(# など)と混用するソート順序を必要とするような場合に使用します。
•スペイン語の ll のようなマルチバイト コレーティング要素、フランス語の ? のようなダイアクリティックス、ドイツ語の ss へ拡張する ß のような文字の拡張および短縮など、言語固有のコレーションに対応する国際的なソート規則(ISR)による方法。
ファイルには、キーごとに異なる ACS を持つことができますが、1 つのキーには 1 つの ACS のみです。したがって、キーがセグメント化されている場合、各セグメントはそのキーに指定された ACS を使用するか、または ACS をまったく使用しないかのいずれかになります。あるファイルに、一部のセグメントにだけ ACS が指定されているキーがある場合、トランザクショナル インターフェイスは指定されたセグメントのみ、ACS を使用してソートします。
ユーザー定義 ACS
ASCII 標準とは別の方法で文字列値をソートする ACS を作成するには、次の表に示す形式を使用します。
表 3 ユーザー定義オルタネート コレーティング シーケンスの形式
位置(オフセット) | 長さ | 説明 |
0 | 1 | 識別バイト。0xAC を指定します。 |
1 | 8 | トランザクショナル インターフェイスに ACS を識別させる、8 バイトの一意の名前。 |
9 | 256 | 256 バイトのマップ。マップ内の 1 バイトの位置はそれぞれ、マップ内でのその位置のオフセットと同じ値を持つコード ポイントに対応します。その位置にあるバイトの値は、コード ポイントに割り当てられるコレーティング ウェイトです。たとえば、コード ポイント 0x61(a)をコード ポイント 0x41(A)と同じウェイトでソートさせるには、同じ値をオフセット 0x61 と 0x41 に設定します。 |
ACS は 16 進エディターで作成されるか、トランザクショナル インターフェイス アプリケーションを作成するときに定義されるので、ユーザー定義 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 として Pervasive PSQL に付属しています。UPPER.ALT は、大文字小文字に関係なくキーをソートすることができます(大文字と小文字を区別しないようにキーを定義することができますが、UPPER は独自の ACS を書くときに良い見本になります)。
例に示すオフセット 0x61~0x7A は、標準の ASCII コレーティング シーケンスから変更されています。標準 ASCII コレーティング シーケンスでは、オフセット 0x61 には値 0x61(小文字の a を表します)が含まれています。UPPER ACS を使用してキーをソートする場合、トランザクショナル インターフェイスは小文字の 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 テーブル名を指定する必要があります。
表 4 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 の標準ロケール テーブルに基づいており、Pervasive PSQL によって提供されます。ISR テーブルは Pervasive PSQL のデータベース エンジンと一緒にインストールされた COLLATE.CFG ファイルに格納されています。複数のデータ ファイルが 1 つの ISR を共有できます。
キー仕様
CREATE(14)または CREATE INDEX(31)を使用してインデックスを作成する場合、キー仕様構造体(インデックス セグメント ディスクリプター)が作成されます。各キー仕様は長さ 16 バイトで、次の情報を含みます。
表 5 キー仕様構造体
フィールド | データ型 | 長さ | NIS セグメント | 説明 |
キー ポジション | Short Int | 2 | レコードの固定長部分でのオフセット | レコード内のキーの相対位置 |
キー長 | Short Int | 2 | 1 | キーの長さ。常に 1 バイト |
キー属性 | Short Int | 2 | xxxxxxx1xxx1xxxx FEDCBA9876543210 | キー属性。属性の詳細については、次のセクションを参照してください。 |
予約済み | Byte | 4 | 適用外 | 未使用 |
拡張データ型 | Byte | 1 | 255(0xFF) | 拡張データ型のうちの 1 つを指定します。新しいデータ型の NULL_INDICATOR が定義されました。 |
ヌル値(非インデックス値) | Byte | 1 | 適用外 | キーの除外値を指定します。 |
予約済み | Byte | 2 | 適用外 | 未使用 |
手動割り当てキー番号 | Byte | 1 | | キー番号 |
ACS(オルタネート コレーティング シーケンス)番号 | Byte | 1 | 適用外 | オルタネート コレーティング シーケンス(ACS)番号 |
表 6 キー属性
属性 | 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 | 0x0008 | 内部使用のみ |
予約済み | 0001 0000 0000 0000 | 0x1000 | |
ページ圧縮 | 0010 0000 0000 0000 | 0x2000 | |
ペンディング キー | 1000 0000 0000 0000 | 0x8000 | 内部使用のみ |
•セグメント キー特有のキー フラグ SEGMENTED(0x0010)、EXTENDED DATA TYPE(0x0100)は、NIS と共に ON に設定する必要があります。
フラグ none は OFF にする必要があります。
フラグ BINARY(0x0004)、ACS(0x0020)は無視されます。
制限と影響
真のヌルのサポートには、いくつかの制限があります。
•参照整合性:現在 MKDE は、DELETE の CASCADE および RESTRICT アクション、UPDATE の RESTRICT アクションのみをサポートしています。SQL-92 は、delete および update の両方に CASCADE、RESTRICT、SET DEFAULT および SET NULL を定義しています。
•セグメント数の制限:ヌル許容列ごとに 2 つのセグメントを占めるため、キーのインデックス付けに使用するインデックス セグメントの数が増加しました。一方、データ ファイルごとのインデックス セグメントの最大数は同じです。
表 7 ページごとの最大インデックス セグメント数
ページ サイズ(バイト数) | キー セグメントの最大数(ファイル バージョン別) |
8.x 以前 | 9.0 | 9.5 |
512 | 8 | 8 | 切り上げ2 |
1,024 | 23 | 23 | 97 |
1,536 | 24 | 24 | 切り上げ2 |
2,048 | 54 | 54 | 97 |
2,560 | 54 | 54 | 切り上げ2 |
3,072 | 54 | 54 | 切り上げ2 |
3,584 | 54 | 54 | 切り上げ2 |
4,096 | 119 | 119 | 119 または 2043 |
8,192 | N/A1 | 119 | 119 または 4203 |
16,384 | N/A1 | N/A1 | 119 または 4203 |
1 N/A は「適用外」を意味します。 2 「切り上げ」は、ページ サイズを、ファイル バージョンでサポートされる次のサイズへ切り上げることを意味します。たとえば、512 は 1,024 に切り上げられ、2,560 は 4,096 に切り上げるということです。 3 リレーショナル インターフェイスで使用できるインデックス セグメントの最大数は 119 です。トランザクショナル インターフェイスの場合、最大数は、ページ サイズ 4,096 では 204、ページ サイズ 8,192 および 16,384 では 420 です。 |
データベース URI
Btrieve ログイン API や、Create または Open オペレーションによる暗黙のログイン機能を使用する上での主要な概念は、データベース URI(Uniform Resource Indicator)です。これは、サーバー上のデータベース リソースのアドレスを記述する構文を提供します。
このセクションでは、Btrieve API で使用する URI の構文と意味を説明します。
構文
URI は次の構文を使用します。
access_method://user@host/dbname?parameters
表 8 データベース URI の要素
要素 | 定義 |
access_method | データベースのアクセスに使用する方法。この要素は必須です。現在、btrv のみがサポートされています。 |
user@ | ユーザー名(省略可能)。必要な場合は、parameters にユーザーのパスワードを指定します。"@" 文字は、host が指定されない場合でもユーザー名を区切るために使用する必要があります。 |
host | データベースが保存されているサーバー。host が指定されていない場合は、ローカル マシンと見なされます。host には、マシン名、IP アドレス、あるいは "localhost" キーワードを指定できます。 メモ:Linux オペレーティング システムのデータベースにアクセスする URI の場合、host は必須要素です。 |
dbname | データベース名(省略可能)。Pervasive PSQL データベース エンジンの DBNAMES.CFG ファイル内のエントリに対応します。データベース名が指定されていない場合は、デフォルトのデータベース "DefaultDB" と見なされます。 |
parameters | 追加オプション パラメーター。&(アンパサンド)文字で区切ります。 •table=テーブル - 特定の SQL テーブル名を指定します。テーブル名はデータベースの DDF に存在している必要があります。 •dbfile=ファイル - ファイルの名前。ファイルの場所は、現在のデータベースに対する、DBNAMES.CFG 内のデータ ファイル ロケーションのエントリに関連しています。相対パスが指定されるので、ドライブ名の使用、絶対パスまたは UNC パスは不可です。データベース エンジンは完全なファイル名を解決します。いかなる方法であっても、Pervasive PSQL クライアントによって「ファイル」が処理されることはありません。空白の埋め込みは可能です。それらの空白はデータベース エンジンによってエスケープされます。 •file=ファイル - 特定のデータ ファイル名を指定します。Pervasive PSQL クライアントはデータベース エンジンへ要求を送る前に、ファイルを標準の状態に変更し、入力名をその変更後の完全修飾 UNC 名で置き換えます。ドライブ名が使用されることがあり、その場合はクライアント側のドライブ名として解釈されます。スペースを含む UNC パスを使用することも可能です。 •pwd=パスワード - クリア テキスト パスワード。Pervasive PSQL クライアントは、転送する前に、クリア テキスト パスワードを暗号化パスワードに変更します。 •prompt=[yes|no] - データベース エンジンからステータス 170(ユーザー名が不正であるか見つからないため、ログインに失敗しました)または 171(パスワードが不正なため、ログインに失敗しました)が返されたとき、ログイン ダイアログ ボックスのポップアップをどのように処理するかを Pervasive PSQL クライアントに知らせます。prompt=yes と指定した場合、リクエスターは[ クライアント資格情報の入力要求]がオフに設定されている場合でも、常にログイン ダイアログ ボックスを表示します。prompt=no と指定した場合、リクエスターは、アプリケーションはステータス 170/171 を直接受け取って、リクエスターにダイアログ ボックスを表示させたくないものと見なします。これは、170 または 171 ステータス コードに対して、認証の入力要求をアプリケーションで処理したい場合に有用です。"yes" または "no" 以外の値は無視されます。リクエスターは[ クライアント資格情報の入力要求]設定に基づいてログイン ダイアログ ボックスを表示します。このオプションは、クライアントの役割を果たしている Linux では無視されます。 |
パラメーターの優先順位
パラメーターの "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 のいずれかの要素で使用する場合は、その文字が実際のテキストではなく特殊文字であると識別されるよう、エスケープ シーケンスを使用する必要があります。エスケープ シーケンスは、特殊文字に相当する標準テキストを表す、別の特殊文字または文字の組み合わせです。
下記の表は、トランザクショナル インターフェイス URI の構文でサポートされている特殊文字と、それに関連付けられたエスケープ シーケンス(パーセント記号と、指定された文字の 16 進値で表されます)を示しています。
表 9 データベース URI における特殊文字
文字 | 説明 | 16 進値 |
/ | ディレクトリとサブディレクトリを区切ります。 | %2F |
? | ベース URI と関連パラメーターを分離します。 | %3F |
% | 特殊文字を指定します。 | %25 |
# | ブックマークまたはアンカーを示します。 | %23 |
& | URI 内のパラメーターを区切ります。 | %26 |
" " | 二重引用符で囲まれている内容全体を示します。 | %22 |
= | パラメーターとその値を区切ります。 | %3D |
空白 | 特別な意味はありませんが、予約されています。 | %20 |
: | ホストとポートを分離します(予約されていますが、現在はサポートされていません)。コロンは IPv6 アドレスでも一部使用されます。 IPv6 を参照してください。 | %3A |
空白文字は URI 仕様で予約されていますが、これは区切り文字として使用されないため、引用符もエスケープ シーケンスもなしで使用できます。それ以外の上記の表内の記号は区切り文字として使用されるため、エスケープする必要があります。
例
このセクションでは、フィールド値の中で使用されている特殊文字を識別するためにエスケープ シーケンスを使用している URI の例を示します。
表 10 エスケープ シーケンスを含んでいる 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:/program%20files/pvsw/mydb/c.mkd | %20 は空白文字を表します。開くファイルは "C:\Program Files\pvsw\mydb\ c.mkd" です。 |
btrv://Bob@myhost/demodata?pwd= mypass%20Is%20%26%3f | ユーザー名が "Bob" でパスワードが "mypass Is &?" |
備考
空のユーザー名または空のパスワードは、ユーザー名やパスワードがないこととは異なるので注意してください。たとえば、btrv://@host/ には空のユーザー名が入っていますが、btrv://host/ にはユーザー名がありません。btrv://foo@host/?pwd= には、"foo" というユーザー名が入っており、パスワードは空です。
URI によっては user:password 構文を使用することもできます。ただし、ここで指定されるパスワードはその後クリア テキストとして転送されます。パスワードがクリア テキストとして転送されないようにするため、user:password 構文を使用してパスワードが提供された場合、Pervasive PSQL データベース URI はそのパスワードを無視します。pwd= パラメーターを使用してパスワードを提供してください。このパスワードは Pervasive PSQL クライアントによって転送される前に暗号化パスワードへ変更されます。
いくつかの URI では user@host:port 構文を使用するサーバー ベースの命名機関を可能にすることもできます。Pervasive PSQL データベース URI は port 要素の指定をサポートします。
例
URL(Uniform Resource Locator)は単に、インターネット上のファイルまたはリソースのアドレスです。データベース URI は同じ概念を利用してサーバー上のデータベースのアドレスを指定します。このセクションでは、Pervasive PSQL データベースにおける、特にトランザクショナル インターフェイス アクセスを使用する場合の URI の構文と意味の例を挙げます。
表 11 トランザクショナル インターフェイス URI の例
例 | 説明 |
btrv://myhost/demodata | サーバー "myhost" 上のデータベース "demodata"。サーバーのオペレーティング システムは、Pervasive PSQL でサポートされる OS のいずれかになります。 |
btrv:///demodata | ローカル マシン上のデータベース "demodata"。ローカル マシンは Windows オペレーティング システムを実行しています。Linux オペレーティング システムでは 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:" を変更するので注意してください。これは、クライアントで "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 接続の処理には異なる方法を使用できます。Pervasive PSQL は IPv6-literal.net 名および、角かっこ([])で囲まれた IPv6 アドレスをサポートします。
『
Getting Started with Pervasive PSQL』の
IPv6 を参照してください。
ダブルバイト文字のサポート
Pervasive PSQL は、ファイル パス内にシフト JIS(日本工業規格)でコード化されたダブルバイト文字を受け入れます(シフト JIS は、日本語のコンピューターに一般に使用されるコード化の手法です)。また、レコードにシフト JIS ダブルバイト文字を格納し、
インターナショナル ソート規則で説明した日本語 ISR テーブルでそれらの文字をソートします。他のマルチバイト文字はレコードに格納できますが、ISR テーブルは文化的に正しい規則に従ってこれらのレコードをソートする目的には現在使用できません。ダブルバイト文字を使用しても、Pervasive PSQL アプリケーションのオペレーションに影響を与えません。
レコード長
すべてのレコードには、レコード長、あるレコードのキーを含むすべてのデータを取り込めるだけの十分な大きさが必要な固定長部分、および、データ ページにレコードを格納するのに必要なオーバーヘッドが含まれています。
物理レコード長を算出するために論理レコード長に追加しなければならないオーバーヘッドのバイト数については、
レコードの圧縮を使用しない場合のレコード オーバーヘッドのバイト数および
レコードの圧縮を使用した場合のレコード オーバーヘッドのバイト数を参照してください。
次の表は、固定長レコードの最大レコード サイズの一覧です。
表 12 固定長レコードの最大レコード サイズ(バイト単位)
ファイル バージョン | システムデータ不使用1 | システムデータ使用2 |
7.x | 4,088 (4096 - 8) | 4,080 (4088 - 8) |
8.x | 4,086 (4096 - 10) | 4,078 (4086 - 8) |
9.0 ~ 9.4 | 8,182 (8192 - 10) | 8,174 (8182 - 8) |
9.5 以上 | 16,372 (16384 - 12) | 16,364 (16372 - 8) |
1 ページ オーバーヘッドおよびレコード オーバーヘッドは、最大ページ サイズから減算して最大レコード サイズを決定します。レコード オーバーヘッドは、各ファイル形式で 2 バイトです。 2 システム データは 8 バイトの追加オーバーヘッドが必要です。 |
ファイルがシステム データを使用し、レコード長が上記の表に示した制限を超える場合、データベース エンジンではそのファイルに対し、データ圧縮を行うことに注意してください。
オプションとして、ファイル内のレコードには可変長部分を含めることができます。可変長レコードには、すべてのレコード内で同じサイズである固定長部分と、各レコードでサイズの異なる可変長部分があります。可変長レコードを使用するファイルを作成する場合、固定長の長さは各レコードの最大長です。最大レコード長は定義しません。
理論的には、可変長レコードの最大長はトランザクショナル インターフェイスのファイル サイズの限界にのみ制限されます。Pervasive PSQLバージョン 9.5 の場合は 256 GB です(9.x から 9.5 までのバージョンでは 128 GB、それ以前のバージョンでは 64 GB)。実際に、最大長は選択したオペレーティング システムやレコード アクセス方法のような要因により制限されます。レコード全体を検索、更新または挿入すると、データ バッファー長パラメーターは 16 ビット符号なし整数であるため、レコード長を 65,535 までに制限します。
実行するオペレーションによって異なりますが、データ バッファーは各種情報の転送に使用するトランザクショナル インターフェイス関数パラメーターです。データ バッファーには、レコード全体、レコードの一部、ファイル仕様などが含まれます。データ バッファーの詳細については、第
5 章
データベースの設計の表
15 を参照してください。
メモ: データと内部ヘッダー情報の合計バイトは、64 KB(0x10000)バイトを超えることはできません。トランザクショナル インターフェイスは、内部の目的で 1,024(0x400)バイトを予約します。つまり、64,512(0xFC00)バイトのデータを持つことができます。
ファイルが非常に大きいレコードを使用する場合は、ファイル内の可変長部割り当てテーブル(VAT)を考慮してください。リンク済みリストとして実装されている VAT は、レコードの可変長部分へのポインターの配列です。VAT は、非常に大きいレコードの各部分へのランダム アクセスを加速します。非常に大きいレコードの例として、バイナリ ラージ オブジェクト(BLOB)やグラフィックスがあります。
非常に大きい可変長レコードを含むファイルについて、トランザクショナル インターフェイスは多数の可変ページにまたがってレコードを分割し、可変長部と呼ぶリンク済みリストでこれらのページを接続します。アプリケーションがチャンク オペレーションを使用してレコードの一部にアクセスし、レコードの一部がレコード自体の先頭を越えたオフセットから始まる場合、トランザクショナル インターフェイスはそのオフセットをシークするための可変長部リンク済みリストの読み取りにかなりの時間を費やすことがあります。そのようなシーク時間を制限するために、ファイルが VAT を使用するように指定できます。トランザクショナル インターフェイスは可変ページに VAT を格納します。VAT を含むファイルでは、可変長部分を持つ各レコードにそれ自体の VAT があります。
トランザクショナル インターフェイスが VAT を使用するのは、ランダム アクセスを加速するためだけでなく、データ圧縮時に使用される圧縮バッファーのサイズを制限するためでもあります。ファイルでデータ圧縮を使用する場合、そのファイルで VAT を使用する必要があります。
データの整合性
以下の機能は、マルチユーザー環境でファイルの整合性を保証しながら、並行アクセスをサポートします。
レコード ロック
アプリケーションは、明示的に、一度に 1 レコード(単一レコード ロック)または一度に複数のレコード(複数レコード ロック)をロックできます。アプリケーションは、レコード ロックを指定する場合、ウェイトまたはノーウェイト条件を適用することもできます。アプリケーションが現在使用できないレコードに対するノーウェイト ロックを要求する場合、つまり、レコードが既に別のアプリケーションでロックされているか、ファイル全体が排他トランザクションでロックされている場合、トランザクショナル インターフェイスはロックを許可しません。
アプリケーションが使用できないレコードに対するウェイト ロックを要求すると、トランザクショナル インターフェイスはデッドロック状態の有無を確認します。デッドロック検出ステータス コードを返す前に待機するようにトランザクショナル インターフェイス を設定することができます。これを行うと、トランザクショナル インターフェイスを内部的に待機させてアプリケーションにはオペレーションを再試行させないので、マルチユーザー環境におけるパフォーマンスを向上させます。
トランザクション
ファイルに対して行う変更が多く、また、これらの変更をすべて行うか、またはまったく行わないかを確実にしなければならない場合は、トランザクションでこれらの変更を行うためのオペレーションを取り込みます。明示的なトランザクションを定義すれば、トランザクショナル インターフェイスに複数のオペレーションをアトミックな単位として処理させることができます。ほかのユーザーは、トランザクションが終了するまでファイルに対して行われた変更がわかりません。トランザクショナル インターフェイスは、排他トランザクションと並行トランザクションの 2 種類のトランザクションをサポートします。
排他トランザクション
排他トランザクションでは、データ ファイルでレコードを挿入、更新または削除するときにトランザクショナル インターフェイスがそのデータ ファイル全体をロックします。ほかのアプリケーションまたは同じアプリケーションの別のインスタンスはファイルを開いてそのレコードを読み取ることができますが、ファイルを変更することはできません。ファイルは、アプリケーションがトランザクションを終了または中止するまで、ロック状態のままになります。
並行トランザクション
並行トランザクションでは、トランザクショナル インターフェイスは、実行するオペレーションによってファイル内のレコードまたはページをロックします。トランザクショナル インターフェイスは、複数のアプリケーション(または同じアプリケーションの複数のインスタンス)が同じファイルの異なる部分に並行トランザクション内で変更を行えるようにしますが、それはこれらの変更が既にロックされているほかのファイル部分に影響を与えない場合に限られます。レコードまたはページは、アプリケーションがトランザクションを終了または中断するまで、ロック状態のままになります。並行トランザクションは、6.0 以降のファイルのみに使用できます。
排他と並行
たとえ要求されたレコードを並行トランザクションが既にロックしていても、クライアントはこれまでどおりレコードを読み取ることができます。ただし、これらのクライアントは排他トランザクション内から処理を行えません。また、要求されたレコードを含むファイルが排他トランザクションで現在ロックされているか、要求されたレコードを並行トランザクションが既にロックしている場合、クライアントは読み取り操作にロック バイアスを適用できません。
クライアントが排他ロックでレコードを読み取ると、トランザクショナル インターフェイスは個々のレコードだけをロックし、レコードが存在するページの残りの部分はロックされない状態のままになります。
メモ: トランザクション内からファイルを開くだけでは、レコード、ページまたはファイルはロックされません。また、トランザクショナル インターフェイスは、読み取り専用のフラグを立てたファイルや読み取り専用モードで開いたファイルはロックしません。
排他トランザクションを使用する場合、Begin Transaction(19 または 1019)オペレーションにノー ウェイト バイアスが付加されない限り、トランザクショナル データベース エンジンはロックされたファイルでほかのクライアントを暗黙に待機させます。アプリケーションは、この暗黙の待機状態でハングしたように見えます。これらの排他トランザクションの寿命が短いと、待機時間に気が付かない場合があります。ただし、暗黙の待機を必要とする多くのクライアントの影響によって、大量の CPU 時間が使用されます。さらに、同じファイル内の複数のポジション ブロックはロックを共有します。
暗黙の待機を必要とする排他トランザクションも、ネットワーク帯域幅を無駄に使用しています。トランザクショナル データベース エンジンは、リクエスターに戻る前に約 1 秒間待機します。リクエスターは待機状態を認識し、トランザクショナル データベース エンジンに操作を返します。したがって、排他トランザクションは余計なネットワーク トラフィックを発生させる可能性もあります。
余計な CPU サイクルとネットワーク トラフィックの量は、ロック済みファイルで待機しているクライアント数と排他トランザクションで必要な時間と相まって、幾何級数的に増加します。
トランザクション一貫性保守
すべてのオペレーションを 1 つのトランザクション ログに記録することによって、
トランザクション一貫性保守とアトミシティを保証するようにトランザクショナル インターフェイスを設定できます。トランザクション一貫性保守は、クライアントが End Transaction オペレーションを発行したときと、トランザクショナル データベース エンジンが正常終了したステータス コードをクライアントに返す前に、トランザクショナル データベース エンジンがログへの書き込みを終了することを保証する機能です。アトミシティは、特定のステートメントが終わりまで実行しない場合にそのステートメントがデータベース内に部分的または不明確な影響を残さないように保証し、それによってデータベースを安定した状態に保つことでデータベースの整合性を保証します。
トランザクション一貫性保守のオーバーヘッドなしでアトミシティが必要な場合は、Pervasive PSQL V8 以降のリリースのトランザクション ログ機能を使用することができます。トランザクション ログの詳細については、『Advanced Operations Guide』を参照してください。
デフォルトでは、トランザクション ログはデフォルトの Windows システム ディレクトリの \MKDE\LOG サブディレクトリにあります。ログは、トランザクショナル データベース エンジンと同じマシン上に存在しなければなりません。トランザクション ログ ディレクトリ設定オプションを使用して、ロケーションを変更できます。
トランザクショナル データベース エンジンは、ログ セグメントと呼ぶ 1 つまたは複数の物理ファイルでトランザクション ログを保守します。現在のログ セグメントがユーザー定義のサイズ上限に達し、変更が待機状態であるファイルがなく、トランザクショナル データベース エンジンがシステム トランザクションを終了すると、トランザクショナル インターフェイスは新しいログ セグメントを開始します。
ログ セグメントには必ず .LOG というファイル拡張子が付きます。トランザクショナル データベース エンジンはログ セグメントのファイル名として、00000001.LOG、00000002.LOG、.... のように、8 桁の 16 進数を使った連続する番号を使用します。
特定ファイルのパフォーマンスを向上させるために、アクセラレイティド モードでファイルを開くことができます(バージョン 6.x トランザクショナル データベース エンジンはアクセラレイティド オープン要求を受け入れましたが、それらの要求をノーマル オープン要求と解釈していました)。アクセラレイティド モードでファイルを開くと、トランザクショナル データベース エンジンは、そのファイルに対するトランザクション ログを実行しません。
メモ: システム障害が発生すると、起動時に削除されないログ セグメントが生成される場合があります。これらのセグメントは、データ ファイルに完全に書き込まれなかった変更を含みます。これらのログ セグメントを削除しないで下さい。どのファイルがこれらのログ セグメントに書き込まれているかはわかりません。これらのデータ ファイルは、次回開かれたときに自動的にロール フォワードするので、何もする必要はありません。
システム データ
Pervasive PSQLは、7.x トランザクション ログ ファイル形式を使用します。トランザクショナル インターフェイスがファイルでトランザクションのログを記録するには、トランザクショナル インターフェイスがログ内のレコードを追跡する際に使用できる重複のない(重複不可能)キーであるログ キーがファイルに含まれている必要があります。1 つ以上の重複のない(重複不可能)キーを持つファイルの場合、トランザクショナル インターフェイスはファイルで既に定義されている重複のないキーのうちの 1 つを使用します。
重複のないキーを持たないファイルの場合、トランザクショナル インターフェイスはファイル作成時にシステム データを含めることができます。トランザクショナル インターフェイスはファイルが 7.x 以降のファイル形式を使用している場合だけファイルにシステム データを含めます。その時点でファイルを作成する場合は、ファイル作成時にファイルにシステム データを含めるようにトランザクショナル インターフェイスが設定されます。システム データは、キー番号 125 で 8 バイトのバイナリ値として定義されます。たとえファイルに重複のないユーザー定義キーがあっても、ユーザーがインデックスを削除することから保護するためにシステム定義ログ キーとも呼ぶシステム データを使用しなければならない場合があります。
ファイルがシステム データを使用し、レコード長が表
12 に示した制限を超える場合、データベース エンジンではそのファイルに対し、データ圧縮を行います。
トランザクショナル インターフェイスがシステム データを追加するのはファイル作成時だけです。既存のファイルにシステム データを追加する場合は、[システム データの作成]設定オプションをオンにしてから Rebuild ユーティリティを使用します。
メモ: トランザクショナル インターフェイスがシステム データを追加すると、その結果、レコードが大きすぎてファイルの既存のページ サイズに収まらない場合があります。その場合、トランザクショナル インターフェイスは、ファイルのページ サイズを自動的に次の適切な大きさに調整します。
シャドウ ページング
トランザクショナル データベース エンジンは、シャドウ ページングを使用して、システム障害が発生した場合に 6.0 以降のファイルが破壊されないようにします。クライアントがトランザクションの内部または外部のページの変更を要求すると、トランザクショナル データベース エンジンはデータ ファイル自体の空いた未使用の物理位置を選択し、シャドウ ページと呼ぶ新しいページ イメージをこの新しい場所に書き込みます。1 回のトランザクショナル インターフェイスの操作で、トランザクショナル データベース エンジンは元の論理ページとすべて同じサイズの複数のシャドウ ページを作成することがあります。
変更がコミットされる、つまり、オペレーションが終了するかトランザクションが終了すると、トランザクショナル データベース エンジンはシャドウ ページを現在のページにし、元のページが再利用可能になります。トランザクショナル データベース エンジンは、有効な再利用可能ページをトラッキングするために、ページ アロケーション テーブルというマップをファイルに格納します。変更がコミットされる前にシステム障害が発生した場合、トランザクショナル インターフェイスは PAT を更新しないため、シャドウ ページを削除し、まだ元の状態のままになっている現在のページを復帰させて使用します。
メモ: この説明では、シャドウ ページング プロセスを単純化しています。パフォーマンスの向上のため、トランザクショナル データベース エンジンは各オペレーションやユーザー トランザクションを個々にコミットせず、それらをシステム トランザクションと呼ぶまとまりにグループ化します。
クライアントがトランザクション内で動作している場合、元の論理ページに対応するシャドウ ページはそのクライアントにしか見えません。ほかのクライアントが同じ論理ページにアクセスしなければならない場合、元の(未変更の)ページが表示されます。つまり、ほかのクライアントには、最初のクライアントがまだコミットしていない変更は表示されません。元のファイルは常に有効でありかつ内部一貫性があるので、シャドウ ページングにより信頼性は向上します。
メモ: バージョン 6.0 より前のトランザクショナル インターフェイスでは、プリイメージングを使用してシステム障害発生時にファイルが破壊されないようにしていました。Pervasive.SQL 7.0 でも、プリイメージングを使用してバージョン 6.0 より前のファイルを保護します。バージョン 6.0 より前のファイルを更新する前に、トランザクショナル インターフェイスは元のファイルから更新されるページを含むテンポラリ プリイメージ ファイルを作成します。トランザクショナル インターフェイスは次に、元のファイルで更新を行います。更新中にシステム障害が発生すると、トランザクショナル インターフェイスはプリイメージ ファイルを使用して元のファイルを復元できます。
ファイルのバックアップ
定期的にファイルをバックアップすることは、データを保護する上で大切なステップです。
ファイルのバックアップについての詳細は、『
Advanced Operations Guide』の
ログ、バックアップおよび復元を参照してください。
イベント ロギング
イベント ロギングは Pervasive PSQL の機能の 1 つで、Pervasive の トランザクショナル インターフェイス、SQL インターフェイスおよびユーティリティ コンポーネントから情報メッセージ、警告メッセージ、エラー メッセージを格納するために使用します。
詳細については、『
Pervasive PSQL User's Guide』の
Pervasive PSQL メッセージ ログを参照してください。
パフォーマンスの向上
トランザクショナル インターフェイス には、パフォーマンスを向上させる以下の機能があります。
システム トランザクション
パフォーマンスを向上し、データの回復を支援するために、トランザクショナル インターフェイスは 1 つまたは複数のコミットされたオペレーション(トランザクションと非トランザクションの両方)をシステム トランザクションと呼ぶオペレーションのまとまりに入れます。トランザクショナル データベース エンジン は、ファイルごとにシステム トランザクションを作成します。システム トランザクションには、同じエンジンで動作する 1 つまたは複数のクライアントからのオペレーションとユーザー トランザクションを含めることができます。
メモ: システム トランザクションと、排他または並行トランザクションを混同しないでください。本書では、「トランザクション」という用語は排他トランザクションまたは並行トランザクション(ユーザー トランザクションとも呼びます)を指しています。ユーザー トランザクションはキャッシュ内のページに変更を加える方法に影響を与えるのに対して、システム トランザクションはキャッシュ内のダーティページをディスク上のファイルの一部にする方法に影響を与えます。トランザクショナル データベース エンジンは、システム トランザクションの起動とプロセスを制御します。
ユーザー トランザクションとシステム トランザクションはともにアトミック トランザクションです。つまり、これらのトランザクションは、すべての変更が行われるか、または変更が何も行われないといった具合に発生します。システム障害が発生すると、トランザクショナル データベース エンジンは障害の起きたシステム トランザクションに関連するすべてのファイルを再度開くときにそれらのファイルを回復します。障害の起きたシステム トランザクションに対して行われたすべての変更、つまり、終了した最後のシステム トランザクション以降にそのエンジン上のすべてのクライアントによって行われたファイルに対するすべてのオペレーションは失われます。ただし、ファイルは矛盾のない状態に復元されるので、システム障害の原因を解決した後にオペレーションを再試行することができます。
Pervasive PSQL は、アクセラレイティド モードで開いたファイルを除くすべてのログ記録可能なファイルのトランザクション一貫性保守を保証します。(ファイルに少なくとも 1 つの重複のない重複不能キーが含まれている場合は、そのファイルをログに記録することができます。キーはシステム定義とすることができます。)トランザクション一貫性保守は、トランザクショナル データベース エンジンが End Transaction に対し正常終了のステータス コードをクライアントに返す前にトランザクション ログへの書き込みを終了することを保証する機能です。アクセラレイティド モードでファイルを開くと、トランザクショナル インターフェイスはファイルをログに記録しません。したがって、トランザクショナル データベース エンジンはファイルにエントリを記録しません。したがって、トランザクショナル データベース エンジンはそのファイルのトランザクション一貫性保守を保証できません。
トランザクショナル データベース エンジンはファイルのシステム トランザクションをロールバックした後、次にファイルを開くときにログを再生します。これにより、システム トランザクションのロールバックによって、ログには格納されているがファイルに書き込まれていないコミット済みのオペレーションが復元されます。
各システム トランザクションは 2 つの段階、つまり、準備と書き込みから構成されています。
準備段階
準備段階では、トランザクショナル データベース エンジンは現在のシステム トランザクションですべてのオペレーションを実行しますが、ファイルにページを書き込みません。トランザクショナル データベース エンジンは必要に応じてキャッシュに登録されていないページをファイルから読み取り、キャッシュにだけ新しいページ イメージを作成します。
以下のアクションはどれも準備段階の終了を引き起こし、書き込み段階の開始を示します。
•トランザクショナル データベース エンジンがオペレーション バンドル制限に達した。
•トランザクショナル データベース エンジンが起動時間制限に達した。
•キャッシュ ページの合計数に対する書き込み準備されたページの比率がシステムのしきい値に達した。
メモ: 一般に、準備段階はトランザクショナル インターフェイス オペレーションの完了後に終了します。しかし、ユーザー トランザクションが完了する前に時間制限またはキャッシュしきい値に達する可能性があります。トランザクショナル インターフェイスは、いずれにしても書き込み段階に切り替わります。
書き込み段階
書き込み段階では、トランザクショナル データベース エンジンは準備段階で準備されたすべてのページをディスクに書き込みます。MicroKernel はまず、すべてのデータ ページ、インデックス ページおよび可変ページを書き込みます。これらのページは実際にはシャドウ ページです。これらのページが書き込まれている間、ディスク上のファイルの一貫性は変わりません。
しかし、PAT ページは現在のページとしてシャドウ ページを指示するため、システム トランザクションの重要部分は PAT ページが書き込まれている間に発生します。この段階を保護するために、トランザクショナル データベース エンジンは FCR にフラグを書き込みます。すべての PAT ページが書き込まれると、最後の FCR が書き込まれるため、ファイルは一貫性を保ちます。この段階でシステム障害が発生すると、次にファイルが開かれたときにトランザクショナル データベース エンジンはシステム障害を認識し、ファイルを直前の状態にロールバックします。次に、トランザクション ログ ファイル内の一貫性保守可能なユーザー トランザクションはすべてファイルに書き込まれます。
システム トランザクションの頻度
頻度が低い
システム トランザクションの頻度を低くすると、ほとんどの構成ではパフォーマンスが向上します。その中には、ファイルが排他的に開かれる、クライアント/サーバー、シングル エンジン ワークステーションおよびマルチエンジン ワークステーション環境があります。
トランザクショナル データベース エンジンがシステム トランザクションの起動回数を少なくすると、ダーティページ、つまり、書き込みが必要なページはメモリ内に長く存在します。アプリケーションが多数の変更操作を行っている場合、これらのページはディスクに書き込まれる前に何回も更新される可能性があります。つまり、ディスクの書き込みが少なくなります。実際に、最も効率の良いエンジンは必要なときだけ書き込まれるエンジンです。
到達するとシステム トランザクションが起動される制限には、オペレーション バンドル制限、起動時間制限、キャッシュ サイズの 3 つがあります。これらの制限に達すると、トランザクショナル データベース エンジンはシステム トランザクションを起動します。この設定の詳細については、『Advanced Operations Guide』を参照してください。
システム トランザクションの回数を減らす最も良い方法は、オペレーション バンドル制限と起動時間制限をさらに高い値に設定する方法です。キャッシュのサイズを増やすこともできます。
頻度が高い
トランザクショナル データベース エンジンがシステム トランザクションを実行する回数を少なくすることの欠点は、ディスクに書き込まなければならないマシンのメモリ内のデータが常に多くなるという点です。停電などのシステム障害が発生すると、失われるデータが多くなります。トランザクショナル データベース エンジンはファイルを一貫性のある使用可能な状態に保つようにつくられていますが、その状態には最新の変更が含まれていない場合があります。もちろん、トランザクション一貫性保守でユーザー トランザクションを使用すると、このリスクが最も少なくなります。パフォーマンスの向上に対してシステム トランザクションの回数を減らすことのリスクをよく考慮してください。
たとえば、アプリケーションがワークステーション エンジンを使用し、低速または信頼性の低いネットワーク接続を通じてリモート ファイルを更新している場合、変更データができるだけ早くディスクに書き込まれるようにシステム トランザクションを頻繁に実行する必要があります。
メモリ管理
キャッシュは、読み取るページをバッファーするためにトランザクショナル データベース エンジンが予約するメモリ領域です。アプリケーションがレコードを要求すると、トランザクショナル データベース エンジンはまず、そのレコードを含むページが既にメモリ内にあるかどうかを確認するためにキャッシュを調べます。そうであれば、トランザクショナル データベース エンジンはレコードをキャッシュからアプリケーションのデータ バッファーに転送します。ページがキャッシュ内になければ、トランザクショナル データベース エンジンはページをディスクからキャッシュ バッファーに読み込んでから要求されたレコードをアプリケーションに転送します。トランザクショナル データベース エンジン キャッシュはローカル クライアントにより共有され、複数のオペレーション間で使用されます。
トランザクショナル データベース エンジンが新しいページをメモリに転送しようとするときにすべてのキャッシュ バッファーがいっぱいであれば、トランザクショナル インターフェイスがキャッシュ内のどのページを上書きするかを LRU(least recently used)アルゴリズムが決定します。LRU アルゴリズムは、最近参照されたページをメモリに保持することによって処理時間を短縮します。
アプリケーションがレコードを挿入または更新すると、トランザクショナル データベース エンジンはまず対応するページのシャドウ イメージを作成し、キャッシュでそのページを変更し、次にそのページをディスクに書き込みます。変更されたページは、トランザクショナル データベース エンジンが新しいページでキャッシュ内のそのページのイメージを上書きできると LRU アルゴリズムが決定するまで、キャッシュ内に残ります。
一般に、キャッシュが大きいほどパフォーマンスが向上するのは、ある時点でメモリ内に保持するページ数を多くすることができるからです。トランザクショナル データベース エンジンを使用して、I/O キャッシュ バッファーに予約するメモリ量を指定することができます。メモリ量を決定する場合は、アプリケーションの必要メモリ量、コンピューターにインストールされた総メモリ量、および、すべての並行 Pervasive PSQL アプリケーションがアクセスする全ファイルの結合サイズを考慮してください。このキャッシュの設定は、[キャッシュ割当サイズ]で行います。
Pervasive PSQL V8 以降のリリースでは、2 番目の動的 L2 キャッシュも使用できます。この動的キャッシュの設定は、[トランザクショナル データベース エンジンの最大メモリ使用量](v9.1 以降では[MicroKernel の最大メモリ使用量])で行います。これらの設定の詳細については、『Advanced Operations Guide』を参照してください。
メモ: 使用可能な物理メモリよりキャッシュを多くすると、実際にパフォーマンスが大きく低下する可能性があるのは、仮想メモリ内のキャッシュメモリの一部がディスク上にスワップされるからです。トランザクショナル データベース エンジン キャッシュは、オペレーティング システムがロードされた後で使用可能な物理メモリの約 60% に設定することをお勧めします。
たとえば、Windows NT 上でこの値を見つけるには、タスクバーで時計を右クリックし、[タスク マネージャー]を選択します。[パフォーマンス]タブを選択すると、ダイアログ ボックスの右下近くに使用可能な物理メモリが表示されます。
ページ プリアロケーション
ページ プリアロケーションは、トランザクショナル データベース エンジンがディスク領域を必要とするときにそのスペースを使用できるようにします。データ ファイルがディスク上の連続する領域を占有する場合、ファイル操作を高速化することができます。速度の向上は、非常に大きなファイルで最も顕著です。この機能の詳細については、
ページ プリアロケーションを参照してください。
Extended オペレーション
Extended オペレーション-Get Next Extended(36)、Get Previous Extended(37)、Step Next Extended(38)、Step Previous Extended(39)および Insert Extended(40)-を使用すると、パフォーマンスを大幅に向上できます。Extended オペレーションは、アプリケーションにもよりますが、トランザクショナル インターフェイスの要求数を 100 分の 1 以下に減らすことができます。これらのオペレーションには、不要なレコードがアプリケーションに送られないように返されたレコードにフィルターをかける機能があります。この最適化手法は、ネットワークを介してデータを送受信しなければならないクライアント/サーバー環境で最も良い結果をもたらします。
これらのオペレーションの詳細については、
マルチレコードのオペレーションを参照してください。
ディスク使用量
トランザクショナル データベース エンジンには、必要なディスク使用量を最小限にするための以下の機能があります。
空きスペース リスト
レコードを削除すると、そのレコードがこれまで占有したディスク領域が空きスペース リストに設定されます。新しいレコードを挿入すると、トランザクショナル インターフェイスは新しい可変ページを作成する前に空きスペース リスト上のページを使用します。空きスペース スレッショルドは、ページが空きスペース リストに表示されるには、可変ページにどれだけの空きスペースが残っている必要があるかをトランザクショナル インターフェイスに示します。
このような空き領域を再利用する方法では、ディスク領域を再利用するようにファイルを再編成する必要がありません。また、空きスペース リストを使用すると、数ページにまたがる可変長レコードの断片化を抑えることができます。空きスペース スレッショルドを高く設定すると断片化を減らすことができますが、ファイルのためのディスク領域がより多く必要になります。
インデックス バランスの実行
インデックス ページがいっぱいになると、トランザクショナル データベース エンジンはデフォルトで新しいインデックス ページを自動的に作成し、いくつかの値をいっぱいになったインデックス ページから新しいインデックス ページへ移動します。[インデックス バランスの実行]オプションをオンにすると、既存のインデックス ページがいっぱいになるたびに新しいインデックス ページを作成しないようにすることができます。インデックス バランスを使用すると、トランザクショナル データベース エンジンはインデックス ページがいっぱいになるたびに、兄弟インデックス ページ内で利用可能な領域を探します。トランザクショナル データベース エンジンは次に、いっぱいになったインデックス ページから空き領域のあるインデックス ページへ値を振り分けます。
インデックス バランスは、インデックス ページの使用度を高めることにより、ページ数を減らし、同レベルのノード間でキーを均等に分配するため、読み取り操作でのパフォーマンスが向上します。しかし、この機能を使用すると、トランザクショナル データベース エンジンはより多くのインデックス ページを調べるために余分な時間が必要になったり、書き込み操作でより多くのディスク I/O が必要になったりする可能性もあります。インデックス バランスの正確な影響は状況によって異なりますが、インデックス バランスを使用した場合、書き込み操作のパフォーマンスは概して約 5 ~ 10% 低下します。
インデックス バランスは「定常状態」のファイルのパフォーマンスに影響を与えます。普通の変更操作は多少遅くなりますが、普通の取得操作は速くなります。平均的なインデックス ページにより多くのキーを収容することによって、これを行います。通常のインデックス ページは 50 ~ 65% まで満たされ、この場合、インデックス バランスされたページは 65 ~ 75% まで満たされます。つまり、検索するインデックス ページが少なくなります。
Create Index(31)でインデックスを作成すると、インデックス ページは 100% フルに近くなるため、これらのファイルが書き込みでなく読み取りについて最適化されます。
メモ: ファイル内の File Flag フィールドに Index Balanced File ビットを設定する方法で、ファイル単位でインデックス バランスを指定することもできます。
[インデックス バランスの実行]オプションを有効にすると、アプリケーションが設定したバランス ファイル フラグの指定とは無関係に、トランザクショナル インターフェイスはすべてのファイルでインデックス バランスを行います。インデックス バランス設定オプションの指定方法については、『Pervasive PSQL User's Guide』を参照してください。
データ圧縮
トランザクショナル インターフェイスはデータ圧縮を使用して、ファイルのレコードを挿入または更新する前にそれらのレコードを圧縮し、それらのレコードを取得するときにレコードを解凍します。圧縮されたレコードの最終の長さはそのレコードがファイルに書き込まれるまで決定できないので、トランザクショナル インターフェイスは常に圧縮されたファイルを可変長レコード ファイルとして指定します。ただし、固定長ファイルでデータ圧縮を使用すると、トランザクショナル インターフェイスは Insert オペレーションと Update オペレーションで、データ ファイルに指定された固定レコード長より長いレコードを生成しません。
トランザクショナル インターフェイスは圧縮されたレコードを可変長レコードとして記録するので、頻繁な挿入、更新および削除を行う場合は個々のレコードがいくつかのデータ ページにわたってフラグメント化される場合があります。トランザクショナル インターフェイスは 1 つのレコードを検索するために複数のファイル ページを読み取らなければならない場合があるので、この断片化によってアクセス時間が遅くなるおそれがあります。しかし、データ圧縮により、多数の繰り返し文字を含むレコードを格納する場合に必要となるディスク容量を、大幅に削減することもできます。トランザクショナル インターフェイスは、5 つ以上の同じ連続文字を 5 バイトに圧縮します。
この機能の詳細については、
レコード圧縮を参照してください。
ブランク トランケーション
ブランク トランケーションはディスク容量を節約します。可変長のレコードを許し、かつデータ圧縮機能を使用しないファイルにのみ適用できます。この機能の詳細については、
ブランク トランケーションを参照してください。