【実務・中級編】 UNIQUE制約 – PostgreSQL

なぜ僕らは「UNIQUE制約」を愛するのか?―データベースの信頼性を守る最後の砦

エンジニアの皆さん、お疲れ様です。

今日はPostgreSQLの「UNIQUE制約」について話をしようと思う。正直、「そんなの教科書に書いてあるよ」と思うかもしれない。でもね、現場で長くデータベースを触っていると、「ここを甘く見ていたせいで、後のデータクレンジングで地獄を見た」という悲鳴を何度聞いたことか。

UNIQUE制約は単なる「重複禁止ルール」じゃない。君が書いたアプリケーションのロジックがどんなにバグっても、データだけは守り抜くという、データベースからの「最後の警告」なんだ。

1. UNIQUE制約の本質:インデックスという名の「番人」

まず、基本をおさらいしよう。UNIQUE制約を設定すると、PostgreSQLは裏で自動的に「B-treeインデックス」を作成する。

ここが重要なんだけど、これは単に「重複を防ぐためだけの機能」じゃないんだ。「そのカラムで検索した時に爆速で結果を返す」ためのインデックスが自動的に付いてくるということ。

つまり、`email`カラムにUNIQUE制約を張ることは、データ整合性を担保するだけでなく、ログイン処理や検索処理のパフォーマンスを担保することと同義なんだよ。

— 基本の形
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email TEXT UNIQUE, — 重複を許さない
username TEXT NOT NULL
);

2. 「カラムの組み合わせ」で制約を作る現場の知恵

実務でよくあるのが、「単一カラムじゃなくて、組み合わせで重複を防ぎたい」というケースだ。例えば、ユーザーごとの「お気に入りリスト」。

「ユーザーID(user_id)」と「商品ID(product_id)」の組み合わせは一つであるべきだよね。これをアプリケーション側の`if`文でチェックするのはやめよう。それはRace Condition(競合状態)の温床だ。必ずデータベース側で制約をかける。

CREATE TABLE favorites (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL,
product_id INT NOT NULL,
— 組み合わせで一意にする
UNIQUE (user_id, product_id)
);

こうしておけば、仮に複数のリクエストが同時に飛んできても、PostgreSQLがしっかり弾いてくれる。安心感が段違いだよ。

3. 注意点:NULLの扱いは「優等生」ではない

ここで一つ、現場でハマりやすい罠を教えておくね。

実は、PostgreSQLにおいて「NULLはNULLと等しくない」んだ。
だから、`UNIQUE(email)`を張ったカラムに、NULLを2回入れることは可能だよ。

  • 1回目:NULL → OK
  • 2回目:NULL → OK
  • 3回目:NULL → OK

「えっ、UNIQUEなのに重複してるじゃん!」と焦る後輩を何人も見てきた。もしNULLも含めて「一つしか許さない」という仕様にするなら、`UNIQUE`制約じゃなくて、`EXCLUDE`句を使った特殊な制約が必要になる。ここは設計時に一度立ち止まって考えてみてほしい。

4. 現場で役立つ「後付け」テクニック

すでに運用中のテーブルにUNIQUE制約を後付けしたいとき、データがすでに汚れていたらどうするか?

`ALTER TABLE`で制約をかけようとすると、重複データがある場合はエラーで止まってしまう。そんなときは、まず重複を特定して掃除してからだ。

— 重複しているデータを特定する
SELECT email, COUNT()
FROM users
GROUP BY email
HAVING COUNT() > 1;

クリーンアップが終わってから、満を持して制約をかける。これがエンジニアの作法だよ。

ALTER TABLE users ADD CONSTRAINT unique_email UNIQUE (email);

最後に:制約は「コードのゴミ」を減らす

最後にアドバイス。
アプリケーションコードの中に、複雑な「重複チェックロジック」を書いていないかな? もしそうなら、それはデータベースに任せていい仕事かもしれない。

データベースが制約で弾いてくれるなら、アプリケーション側は「エラーが起きたら例外をキャッチして、ユーザーに分かりやすく伝える」というシンプルな設計に集中できる。

データベースの制約を「邪魔者」と思わず、「自分のコードを助けてくれる相棒」だと思って付き合ってみてほしい。そうすれば、君が書くシステムはもっと堅牢で、もっと美しいものになるはずだよ。

それじゃ、また現場で会おう。いいコードを!

コメント

タイトルとURLをコピーしました