カテゴリ: データベース 更新日: 2026/04/07

PostgreSQL初心者ガイド!制約(主キー・外部キー・UNIQUE)を徹底解説

PostgreSQLの制約とは?主キー・外部キー・UNIQUEを整理
PostgreSQLの制約とは?主キー・外部キー・UNIQUEを整理

先生と生徒の会話形式で理解しよう

生徒

「PostgreSQL(ポストグレスキューエル)というのを使ってみようと思うのですが、データを入れるときに『変なデータが入らないように守る仕組み』があるって聞きました。それって何ですか?」

先生

「それは『制約(せいやく)』のことですね。データベースに保存するデータが、デタラメな内容にならないようにするためのルールのことです。例えば、会員名簿で同じIDの人が二人いたら困りますよね? そういう間違いを機械が自動で防いでくれるんですよ。」

生徒

「なるほど!間違えて消しちゃいけないデータを守ってくれたりもするんですか?」

先生

「その通りです!今日は、特によく使われる『主キー』『外部キー』『UNIQUE(ユニーク)制約』について、名簿を例に挙げてゆっくり見ていきましょう。」

1. データベースの「制約」とは何か?

1. データベースの「制約」とは何か?
1. データベースの「制約」とは何か?

PostgreSQLなどのリレーショナルデータベース(表形式でデータを管理するシステム)において、「制約」とは、テーブルに保存されるデータが守らなければならないルールのことです。 パソコンを触ったことがない方でも、「書類の記入漏れがないかチェックする窓口」をイメージすると分かりやすいでしょう。

もし制約がなかったら、名前が空欄のまま登録されたり、メールアドレスが重複して誰のものか分からなくなったりと、データベースの中身がめちゃくちゃ(整合性が失われた状態)になってしまいます。 これから紹介する3つの主要な制約を学ぶことで、正しく安全なデータベース設計の基礎が身に付きます。

エンジニアの必須スキル「SQL」を、 図解と豊富な練習問題でゼロから体系的に学びたい人へ。 MySQLやPostgreSQLなど、各種データベースに対応した不朽の入門書です。

SQL 第2版 ゼロからはじめるデータベース操作をAmazonで見る

※ Amazon広告リンク

2. 主キー(PRIMARY KEY)でデータを特定する

2. 主キー(PRIMARY KEY)でデータを特定する
2. 主キー(PRIMARY KEY)でデータを特定する

主キー(しゅきー)は、その行が「世界に一つだけ」であることを保証するための最も重要な制約です。 例えば、学校の出席番号や、会社員であれば社員番号のようなものです。

主キーには2つの大きな特徴があります。

  • 重複してはいけない: 同じ番号の人が二人いてはいけません。
  • 空(NULL)であってはいけない: 番号が割り振られていない人は登録できません。

以下の「社員名簿(employees)」テーブルを見てみましょう。ここでは「id」を主キーとして設定しています。


id | name     | department | join_date
---+----------+------------+------------
1  | 山田太郎 | 営業部     | 2023-04-01
2  | 佐藤花子 | 開発部     | 2023-05-15
3  | 鈴木一郎 | 総務部     | 2023-06-01
4  | 田中愛   | 営業部     | 2023-07-20

ここで、新しく「idが2」の人を追加しようとすると、PostgreSQLが「すでに2番は使われています!」とエラーを出して止めてくれます。


-- すでに存在するid=2を登録しようとする(エラーになります)
INSERT INTO employees (id, name, department, join_date)
VALUES (2, '高橋健二', '開発部', '2024-01-10');

実行結果は以下のようになります。


ERROR: duplicate key value violates unique constraint "employees_pkey"
DETAIL: Key (id)=(2) already exists.

このように、主キーを設定することで、データを1行ずつ確実に区別できるようになります。

3. UNIQUE制約で重複を防ぐ

3. UNIQUE制約で重複を防ぐ
3. UNIQUE制約で重複を防ぐ

UNIQUE(ユニーク)制約は、その列に「同じ値を二度と入れない」というルールです。 主キーと似ていますが、大きな違いは「主キーは1つのテーブルに1つだけ」ですが、UNIQUE制約は複数の列にかけることができます。

例えば、メールアドレスや電話番号です。社員番号とは別に、個人の連絡先が重複すると連絡ミスが起きてしまうため、UNIQUE制約を設定して守ります。

以下のテーブルでは、「email」列にUNIQUE制約がかかっています。


id | name     | email              | phone
---+----------+--------------------+--------------
1  | 山田太郎 | taro@example.com   | 090-1111-1111
2  | 佐藤花子 | hanako@example.com | 090-2222-2222
3  | 鈴木一郎 | ichiro@example.com | 090-3333-3333
4  | 伊藤純   | jun@example.com    | 090-4444-4444

誰かがすでに使っているメールアドレスで新しく登録しようとすると、エラーが発生します。


-- 佐藤花子さんと同じメールアドレスで登録しようとする
INSERT INTO employees_contacts (id, name, email)
VALUES (5, '渡辺修', 'hanako@example.com');

実行結果:


ERROR: duplicate key value violates unique constraint "unique_email"

このように、主キーではないけれど、中身が重なってほしくない情報に対してUNIQUE制約を使います。

4. 外部キー(FOREIGN KEY)でテーブル同士を繋ぐ

4. 外部キー(FOREIGN KEY)でテーブル同士を繋ぐ
4. 外部キー(FOREIGN KEY)でテーブル同士を繋ぐ

外部キー(がいぶきー)は、別のテーブルにあるデータと「紐付け(ひもづけ)」を行うための制約です。 これは「関連性のチェック」とも言えます。

例えば、「注文データ」と「商品リスト」を想像してください。商品リストに存在しない幽霊商品の注文が入ったら困りますよね。 外部キーを設定すると、「商品リストにある商品IDしか、注文データに入力できない」という制限をかけることができます。

まずは「部署(departments)」テーブルがあります。


dept_id | dept_name
--------+----------
10      | 営業部
20      | 開発部
30      | 人事部

次に、外部キーを設定した「社員(staff)」テーブルです。ここでの「dept_id」は部署テーブルを参照しています。


staff_id | name     | dept_id
---------+----------+---------
101      | 山田     | 10
102      | 佐藤     | 20
103      | 鈴木     | 10
104      | 高橋     | 30

もし、存在しない「部署番号99」を無理やり登録しようとしたらどうなるでしょうか?


-- 部署テーブルに存在しない「99」を入れようとする
INSERT INTO staff (staff_id, name, dept_id)
VALUES (105, '田中', 99);

実行結果:


ERROR: insert or update on table "staff" violates foreign key constraint "staff_dept_id_fkey"
DETAIL: Key (dept_id)=(99) is not present in table "departments".

PostgreSQLが「そんな部署はありませんよ!」と怒ってくれました。 また、外部キーの凄いところは、「使われているデータを勝手に消させない」という機能もあります。 もし、営業部(10番)に所属している社員がいるのに、部署テーブルから営業部を削除しようとするとエラーになり、データの整合性を守ってくれます。

5. なぜ制約を使う必要があるのか?

5. なぜ制約を使う必要があるのか?
5. なぜ制約を使う必要があるのか?

プログラミング未経験の方は、「そんなに厳しくしなくても、気をつけて入力すればいいのでは?」と思うかもしれません。 しかし、システムを長く運用していると、人間の操作ミスは必ず起こります。

数万件、数十万件という膨大なデータを扱うとき、1つの間違いがシステム全体の故障に繋がることもあります。 PostgreSQLの制約は、いわば「データの防波堤」です。 あらかじめガッチリとルールを決めておくことで、将来のトラブルを未然に防ぎ、信頼性の高いシステムを作ることができるのです。

今回学んだ「主キー」「UNIQUE制約」「外部キー」は、どれもテーブル設計の基本中の基本です。 これらを組み合わせることで、整理整頓された美しいデータベースを構築できるようになります。

カテゴリの一覧へ
新着記事
New1
Rails
RailsモデルとActive Record基礎|ID戦略を完全理解!AUTO INCREMENT・UUID・ULIDの比較と導入手順
New2
データベース
データベース設計の基本を完全ガイド!SQLテーブル設計の考え方を初心者向けにやさしく解説
New3
Ruby
初心者必見!RubyのNoMethodError・NameError・SyntaxErrorを完全解説
New4
Rails
RailsのNamespaced ControllerとAdmin構成を完全解説!初心者でもわかるルート・認可・レイアウトの分離
人気記事
No.1
Java&Spring記事人気No1
Ruby
WindowsでRubyをインストールする方法!RubyInstallerとMSYS2を使った完全ガイド
No.2
Java&Spring記事人気No2
Rails
Railsのimportmap入門|Node不要でJavaScriptを使う方法と落とし穴をやさしく解説
No.3
Java&Spring記事人気No3
データベース
PostgreSQLが遅い原因を解決!初心者向けデータベースチューニングと高速化の基本
No.4
Java&Spring記事人気No4
Rails
Railsテスト入門:FactoryBotの使い方を完全解説!trait・association・sequenceでテストデータ最適化
No.5
Java&Spring記事人気No5
データベース
SQLで複数テーブルを結合する方法を徹底解説!初心者でも図解でわかるJOINと集計の基本
No.6
Java&Spring記事人気No6
データベース
PostgreSQLのCTE(WITH句)完全解説!複雑なSQLを整理して読みやすくする書き方
No.7
Java&Spring記事人気No7
Ruby
Rubyの論理演算子をマスター!and/orと&&/||の違いと優先順位の罠
No.8
Java&Spring記事人気No8
Ruby
Rubyの始め方ガイド:インストールから最初のHello Worldまで(Windows/Mac/Linux)