キー は、 特定の行 (単数または複数) を識別したりそれらにアクセスしたりするために使用可能な一連の列です。 キーは、表、索引、または参照制約の記述で識別されます。 同じ列を複数のキーの一部にすることができます。
固有キー は、 2 つの値が同じにならないように強制されているキーです。 固有キーの列にヌル値を含めることはできません。 たとえば、従業員番号の列の各値は 1 人の従業員だけを指すものなので、 これを固有キーとして定義することができます。 2 人の従業員が同じ従業員番号を共有することはできません。
キーの固有性を強制させるために使用する機構を固有索引 と呼びます。 表の固有索引とは、 それぞれの値が固有の行を識別する (機能的に判別する)、 1 つの列または複数の列の順序集合のことです。 固有索引にはヌル値を含めることができます。
基本キー は、 1 つの表上に定義された固有キーの 1 つですが、 1 番目に重要なキーとして選択されたものです。 1 つの表上には 1 つだけの基本キーが可能です。
基本キーに対する 1 次索引 は自動的に作成されます。 1 次索引は、データベース・マネージャーが表の行に効率的にアクセスする ために使用するもので、データベース・マネージャーが基本キーを固有 のものにするためのものです。 (さらに、非基本キー列にも索引を定義して、 照会の処理時に効率的にデータにアクセスできます。)
表に "本来の" 固有キーがない場合や、 到着順によって固有の行を区別する場合は、 タイム・スタンプをキーの一部として使用するのが効果的な場合もあります。 (識別列の定義も参照。)
サンプル表の一部に使用されている基本キーは、次のとおりです。
PROJECT 表の一部に基本キーを示した例を次に示します。
PROJNO (基本キー) | PROJNAME | DEPTNO |
---|---|---|
MA2100 | Weld Line Automation | D01 |
MA2110 | Weld Line Programming | D11 |
表のすべての列に重複値が含まれる場合、 1 つの列だけに基本キーを定義することはできません。 複数の列を使ったキーは複合キー と呼ばれます。 列の値の組み合わせは、固有のエンティティーを定義するものでなければなりません。 複合キーを簡単に定義することができない場合、 固有の値を持つ新しい列を作成するのも 1 つの方法です。
次の例は、複数の列を含む基本キー (複合キー) を示すものです。
EMPNO (基本キー) | PROJNO(基本キー) | ACTNO (基本キー) | EMPTIME | EMSTDATE (基本キー) |
---|---|---|---|---|
000250 | AD3112 | 60 | 1.0 | 1982-01-01 |
000250 | AD3112 | 60 | .5 | 1982-02-01 |
000250 | AD3112 | 70 | .5 | 1982-02-01 |
キーの候補を識別するには、 固有のエンティティーを定義する最小限の列を選択してください。 キー候補は複数個あるかもしれません。 表 2 には、キーの候補となるものがたくさん示されています。EMPNO、 PHONENO、 および LASTNAME 列は、 それぞれ従業員を固有に識別するものとなります。
いくつかのキーの候補から基本キーを選択するときには、 持続性、固有性、安定性を基準にします。
例の中の 3 つの候補キーのうち、上記の基準すべてにかなうのは EMPNO だけです。 従業員は入社時に電話番号を持っていないかもしれません。 名字は変わる可能性があるため、ある時点で固有であっても、 そのことが保証されているわけではありません。 基本キーとしては従業員番号列が最もよいと言えます。 従業員には一度だけ固有の番号が与えられ、 大抵は会社をやめない限りその番号が変更になることはありません。 各従業員は必ず番号を持つため、従業員番号列の値には持続性があります。
識別列 は、DB2 が自動的に表の各行に固有の数値を生成する手段となります。 表には、識別属性が定義されている単一列を入れることができます。 識別列の例には、 オーダー番号、従業員番号、在庫番号、および問題番号があります。
識別列の値は常に生成するか、デフォルトで生成することができます。
識別列は、固有の基本キー値を生成するタスクに理想的なものです。 アプリケーションは識別列を使用することにより、 データベースの外で独自の固有カウンターが生成されたときに 生じる可能性がある並行性とパフォーマンス上の問題を避けることができます。 たとえば、一般的な 1 つのアプリケーション・レベル実装では、 カウンターを含む 1 行の表を保守します。 それぞれのトランザクションはこの表をロックし、数値を増分してから、コミットします。 つまり、一度に 1 つのトランザクションのみがカウンターを増分できます。 対照的に、カウンターが識別列を介して保守されている場合、 カウンターはトランザクションによりロックされないため、 さらに高いレベルの並行性を実現することができます。 カウンターを増分したトランザクションがコミットされていなくても、 続くトランザクションがカウンターを増分できなくなることはありません。
識別列のカウンターは、トランザクションから独立して増分 (または減分) されます。 特定のトランザクションが識別カウンターを 2 回増分した場合、 同時に他のトランザクションが同じ識別カウンターを増分している (つまり、行を同じ表に挿入している) 可能性があるため、 このトランザクションで生成された 2 つの数の間にギャップが検出されることがあります。 アプリケーションに連続する一連の数が必要な場合、 そのアプリケーションは識別列がある表に排他ロックを行う必要があります。 この決定は、結果として並行性が失われることを比較検討して行わなければなりません。 さらに、識別列の値を生成したトランザクションがロールバックしたため、 または値の範囲をキャッシュしたデータベースが、 キャッシュされたすべての値が割り当てられる前に非活動化されたため、 特定の識別列の数値にギャップが生じたように見えることがあります。
識別列によって生成された順次数値には、次の付加的な特性があります。