7.7. キー

著者: Herouth Maoz ()によって 書かれました。もともとは 1998 年 3 月 2 日のユーザメーリングリスト でこのような質問の答えとして現われました。 "PRIMARY KEY と UNIQUE 制約の違いは何ですか?"

Subject: Re: [QUESTIONS] PRIMARY KEY | UNIQUE


            下記の違いは何ですか:

              PRIMARY KEY(fields,...)と
              UNIQUE (fields,...)

       - これは別名ですか?
       - もしPRIMARY KEY が既に一意ならば、なぜ
         UNIQUE と呼ばれる別のキーがあるのですか?

主キー(primary key)は特定の行を認別するためのフィールドです。 例えば、ある人を識別するためには社会保証番号があります。

単純に UNIQUE である組み合せのフィールドは、行の特定とは関係ありません。 それは単に整合性制約なのです。例えば、複数のリンク集合を持っていると します。それぞれの集合は一意な数字で特定され、それが主キーとよばれます。 このキーはリレーションで使われます。

しかし、アプリケーションはそれぞれの集合が一意な名前も持つことを 要求します。なぜでしょう? それは、集合を修正する人間が識別できるからです。 もし"生命科学"と呼ばれる集合が二つあり、29882 ではなく 24433 という番号 の付けられた方が必要だという場合、非常にわかりにくくなってしまいます。

ですから、ユーザは集合を名前で選択します。したがって、データベースの中で 名前は一意であることを確認しなければいけません。しかし、データベースの 中で、集合の名前から集合テーブルに関係するものはありません。 それはあまり効率が良くありません。

更に、一意であるにも関わらず、集合名は実際に集合を定義するわけでは ありません。例えば、もし誰かが"生命科学""生物学"に変えようとしても、それは名前だけが違う同じ集合 のままです。名前が一意である限りはそれで大丈夫です。

ですから、

なぜ標準SQL構文では非一意なキーが明白に定義されて いるのでしょう? まず、インデックスは実装に依存するということを 理解しなければいけません。SQLは実装を定義するのではなく、 単にデータベースのデータ中にあるリレーションのみを定義します。 Postgresは非一意なインデックスを認めませんが、 SQLキーを強制するために使われるインデックスは 常に一意です。

したがって、カラムにインデックスがないにも関わらず、そのカラムの どんな組み合せでもテーブルを問い合わせることができます。そのインデックス は単に、一般的に使われる問い合わせをより効率良く行うために RDBMSが提供する実装の手助けです。いくつかの RDBMSは、キーをメインメモリに残すなどの付加を 与えます。それらは特別なコマンドを持っています。例えば、

CREATE MEMSTORE ON table COLUMNS cols
(これは実際にあるコマンドではなく、ただの例です。)

実際、主キーもしくはフィールドの一意な組み合せを作る時、 SQL規格のどこでもインデックスが作られたことや キーによるデータの抽出が順スキャンよりも効率がよくなるとは 言っていません!

ですから、もし一意ではないフィールドの組み合せを二次キーとして使いたい 場合、何も指定する必要がありません。ただその組み合せで抽出を 始めるだけです! しかし、もし抽出を効率良く行いたい場合は、 使っているRDBMSプロバイダが提供する方法に 頼らなくてはいけません。例えばインデックスや、空想上の MEMSTORE コマンドや、指定されたキーのコンビネーションに基づいた 沢山の問い合わせを送ったという事実に基づいて知らないうちにインデックス を作る賢いRDBMSかもしれません。(それは経験から学ぶ ことができるのです。)