ユニーク制約とユニークインデックス
カラムの値がユニークになるようにするときに、「"ユニーク制約"をつけよう」なんていう言い方をしていたが、この"ユニーク制約"が具体的に何を指しているか、意外にちゃんと把握してなかった
※postgreSQLのお話
そもそもユニークはどうやって実現されているのか
postgreSQLにおいて、値のユニークさはユニークインデックスで実現されている
11.6. 一意インデックス #
ユニークインデックスがあるカラムに対してデータを挿入/更新する場合、
ユニークインデックス上に同じ値がないかを確認する。
問題がなければデータ処理がそのまま進む。
ユニークインデックスを作るためには
ユニークインデックスを作る場合、二つの方法がある。
- ユニーク制約を追加する
- ユニークインデックスを直接作成する
ユニーク制約
出ました「ユニーク制約」
postgreSQLにおいて、「ユニーク制約」とは、pg_constraintsテーブルに格納されてる制約データのことを指します
制約
// テーブル作成時
CREATE TABLE products (
product_no integer UNIQUE,
name text,
price numeric
);
// あとで追加
ALTER TABLE users
ADD CONSTRAINT users_email_key UNIQUE (email);
pg_constraintsにユニーク制約を追加すると、ユニークインデックスも自動で作成されます
ユニークインデックスを直接作る
ユニークインデックスを作るクエリはこんな感じ
CREATE UNIQUE INDEX name ON table (column [, ...]);
これはpg_constraintsに制約は追加しないで、ユニークインデックスだけを作ってくれる。
Railsの場合
Railsでユニーク性を担保したい場合は、こんな感じで書くことが多い
add_index :テーブル名, :カラム名, unique: true
これはユニーク制約を追加してるわけではなくて、ユニークインデックスを直接作成してる
どっちでユニークを実現するべき?
ネットで調べたり、AIに聞いたりしたけどあんまよくわかんなかった。
とりあえず、ユニーク制約があるというルールをDBで明示的にしておきたい場合は、pg_constraintsに追加した方が良いらしい。
追加しておくことでスキーマに明記され、DB移行時などにルールが漏れることがなくなるとか。
まとめ
ユニーク制約とは、カラムの値のユニークさを担保するルールを指し、pg_constraintsというテーブルに保存されている。
ユニークインデックスとは、実際に値がユニークであるかどうかを判定するためのインデックスを指す。
Discussion