単一列へのUNIQUE制約の適用
SQL Serverでテーブルを作成する際、特定のカラムの値を一意に保つ必要がある場合、UNIQUEキーワードをカラム定義に追加します。これにより、データベースエンジンはそのカラムに重複する値が挿入されることを防ぎます。
CREATE TABLE AppUsers (
UserID INT IDENTITY(1,1) PRIMARY KEY,
LoginName NVARCHAR(100) UNIQUE,
Role VARCHAR(50)
);
上記の例では、LoginNameカラムに対してUNIQUE制約が設定されているため、同じログイン名を持つレコードは複数存在できません。
複数列の組み合わせによる一意性制約
単一のカラムではなく、複数のカラムの組み合わせ(コンポジットキー)に対して一意性を求めるケースもあります。この場合、CONSTRAINT句を使用して制約名を明示的に指定し、対象のカラムをリスト化します。
CREATE TABLE OrderDetails (
DetailID INT PRIMARY KEY,
OrderNumber INT,
ProductCode VARCHAR(20),
Quantity INT,
CONSTRAINT UQ_Order_Product UNIQUE (OrderNumber, ProductCode)
);
この定義により、OrderNumberとProductCodeのペアが同一である行はテーブル内に存在できなくなります。一方で、異なる注文番号であれば同じ商品コードが使用可能です。
既存テーブルへの制約追加
テーブル作成後に制約を追加する場合は、ALTER TABLE文を使用します。
ALTER TABLE AppUsers
ADD CONSTRAINT UQ_AppUsers_LoginName UNIQUE (LoginName);
PRIMARY KEYとの相違点
一意性を保証するという点ではUNIQUEとPRIMARY KEYは共通していますが、データベース内部での挙動や用途には明確な違いがあります。
| 特性 | PRIMARY KEY | UNIQUE |
|---|---|---|
| 一意性 | 必須。重複不可。 | 必須。重複不可。 |
| NULL値の許容 | 不可(NOT NULL制約が暗黙的に適用される)。 |
可能(1つのカラムにつき1つのNULL値のみ許可される挙動はSQL Serverの設定によるが、基本的にはNULLは特別扱いされる)。 |
| テーブル内の数 | 1つのテーブルに1つのみ。 | 1つのテーブルに複数定義可能。 |
| インデックス種類 | デフォルトでクラスタ化インデックスを作成。 | デフォルトで非クラスタ化インデックスを作成。 |
| 主な用途 | レコードを識別するための主たるキー(IDなど)。 | ビジネスロジック上の一意性が必要な属性(メールアドレス、ユーザー名など)。 |
これらの違いを理解し、適切に使い分けることで、データ整合性を維持しつつ効率的なクエリ実行計画を設計できます。例えば、エンティティを一意に識別する surrogate key にはPRIMARY KEYを、業務上の制約として重複を許さない属性にはUNIQUE制約を利用するのが一般的です。