主キー・一意キー制約とユニークインデックスについて | システム職人の日常

システム職人の日常

システム職人の日常について、とか

テーマ:
これまで「一意キー」という言葉を、
このブログでも何の気なしに使って
いたので、整理の意味も含めて、
「主キー(PRIMARY KEY)」
「一意キー(UNIQUE)」
「ユニーク。インデックス(UNIQUE INDEX)」
について説明したいと思います。

まず、「主キー(PRIMARY KEY)」と
「一意キー(UNIQUE)」はテーブルに
付与する「制約(CONSTRAINT」です。
意味としては
・テーブルに格納されるレコードに
 制限を付けるためのもの
で、「オブジェクト」ではありません。
なので、「CREATE ~」とはせずに、
「CREATE TABLE」内に記述するか、
「ALTER TABLE ~」として、文字通り
「TABLE」オブジェクトに「付与」する
ことになります。
そして、付与される「制限事項」は
どちらも「テーブル内で重複しない」
ことです。なので、主キーも一意キーも
「制限事項」としては全く同じものに
なります
では何が違うのかというと、
・主キーは1テーブルにつき1つだけ
 しか作ることが出来ない
・一意キーは1テーブルにいくつでも
 作ることが出来る
というだけです。
PRIMARYを英和辞典で調べると、
 第一の、初級の、基礎的な、第1位の、
 主要な、最初の、初期の、本来の
みたいな意味が載っていると思いますが、
まさに「そういう」キーとして使います。

対して「ユニーク・インデックス」は
オブジェクトです。作成するには、
「CREATE UNIQUE INDEX ~」とします。
「制約」が領域を必要としないのに対して
「インデックス」は領域を必要とするのも
データを格納する「オブジェクト」だから
です。
ただし、「インデックス」オブジェクトは
元となる「テーブル」オブジェクトが存在
する、いわば「子分」みたいなものです。

ちなみに主キーと一意キーは、この
ユニーク・インデックスを「使って」
テーブル内に値の重複がないかどうかを
確認しています。
なので、主キーや一意キーには、必ず
対応する UNIQUE INDEX が存在します。
CREATE TABLE文内に PRIMARY KEY や
UNIQUE制約の定義を記述した場合、
Oracle は制約と同じ名前で暗黙的に
UNIQUE INDEX を作成します。
つまり、

-- 1. CREATE TABLEで制約も定義する場合
CREATE TABLE ZZZ(
  KEY_1    NUMBER,
  KEY_2    VARCHAR2(8),
  DATA_1   VARCHAR2(64),
  DATA_2   VARCHAR2(256),
  CONSTRAINT PK_ZZZ
    PRIMARY KEY(KEY_1, KEY_2),
  CONSTRAINT UK_ZZZ
    UNIQUE(DATA_1)
)
/

とする場合と、

-- 2. オブジェクトと制約を個別に定義する場合
-- CREATE TABLEは列定義のみ
CREATE TABLE ZZZ(
  KEY_1    NUMBER,
  KEY_2    VARCHAR2(8),
  DATA_1   VARCHAR2(64),
  DATA_2   VARCHAR2(256)
)
/
-- 1の主キーの名前でインデックス作成
CREATE UNIQUE INDEX PK_ZZZ
  ON ZZZ(KEY_1, KEY_2)
/
-- 上記のインデックスをUSING指定して主キーを付与
ALTER TABLE ZZZ ADD
  CONSTRAINT PK_ZZZ
    PRIMARY KEY(KEY_1, KEY_2)
    USING INDEX PK_ZZZ
/
-- 1の一意キーの名前でインデックス作成
CREATE UNIQUE INDEX UK_ZZZ
  ON ZZZ(DATA_1)
/
-- 上記のインデックスをUSING指定して一意キーを付与
ALTER TABLE ZZZ ADD
  CONSTRAINT UK_ZZZ
    UNIQUE(DATA_1)
    USING INDEX UK_ZZZ
/

とする場合でできあがるテーブルと
インデックスは全く同じになります。

主キーと一意キーについての説明と、
ユニーク・インデックスとの関係に
ついては以上です。


次回は「外部キー(FOREIGN KEY)」の
予定です。