PSQL Programmer's Guide (v11)

キー属性 (トランザクショナル インターフェイス)

以下のセクションでは、キーを定義するときに指定できる属性について説明します。

キー属性の解説

このセクションでは、キーに割り当てられる以下の属性について説明します。

セグメント化

キーは、各レコード内の 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 バイト整数ならば、キー バッファー パラメーターは以下のいずれかにすることができます。

基本的には、トランザクショナル インターフェイスはキー バッファーとして使用されるメモリの場所へのポインターを取得します。トランザクショナル インターフェイスはそのメモリの場所に、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 SP1 には、列のデータをヌル値として識別する方法が 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 オペレーションの動作と一貫性があります。

別個の(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 を使用して、次のようにキーをソートすることができます。

ファイルには、キーごとに異なる 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 を共有できます。

サンプル コレーションについては、付録 A インターナショナル ソート規則を使用したコレーションのサンプルを参照してください。

キー仕様

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
内部使用のみ

制限と影響

真のヌルのサポートには、いくつかの制限があります。


データ型 (トランザクショナル インターフェイス)

データベース URI (トランザクショナル インターフェイス)