データベーススペシャリスト 2014年 午前2 問03
問題文
関係データベースの表を設計する過程で、A 表と B 表が抽出された。主キーはそれぞれ列 a と列 b である。この二つの表の対応関係を実装する表の設計に関する記述のうち、適切なものはどれか。

選択肢
ア:A表とB表の対応関係が1対1の場合、列 a を B 表に追加して外部キーとしてもよいし、列b をA表に追加して外部キーとしてもよい。(正解)
イ:A表とB表の対応関係が1対多の場合、列 b をA表に追加して外部キーとする。
ウ:A表とB表の対応関係が多対多の場合、新しい表を作成し、その表に列 a か列b のどちらかを外部キーとして設定する。
エ:A表とB表の対応関係が多対多の場合、列 a を B 表に、列b を A表にそれぞれ追加して外部キーとする。
🔒 解説は解答すると表示されます
1対1関係の実装方法【午前2解説】
正解の理由
選択肢アが正しいのは、1対1の対応関係は「どちらの表に外部キーを置いても表現できる」からです。ただし「外部キーを置くだけ」で1対1が自動的に保証されるわけではありません。片側に外部キーを置く場合、その外部キー列に一意制約(UNIQUE)を付与するか、外部キー自体を主キー(PK)にすることで、1つの行が対応表の一つの行にしか紐づかないことを明示的に強制する必要があります。したがって「どちらに外部キーを置いてもよい」点は正しいが、1対1を保証するための一意性制約の付与が前提です。
解法ステップ
- 関係の多重度(1対1、1対多、多対多)を判定する。
- 多重度に基づき、どちらの表に外部キーを置くべきかを判断する。
- 1対多:多側に外部キーを置く(多側の行が単数側の主キーを参照)。
- 1対1:どちらでも良いが、一意性を保証するための制約が必要。
- 多対多:中間表(結合表)を作り、両側の主キーを外部キーとして持たせる。
- 実装上の制約(UNIQUE、NOT NULL、主キー化、ON DELETE/UPDATE の振る舞い)を設計に反映する。
- 必要なら中間表の主キー設計(複合PKやサロゲートキー)を決める。
選択肢別の誤答解説
- ア: 正(ただし条件付き)
- 1対1では、列 a を B 表に追加して a を外部キーとするか、列 b を A 表に追加して b を外部キーとするどちらでも対応を表現できます。しかし1対1を制約として保証するには、外部キー側の列に UNIQUE 制約を付けるか、外部キーをその表の主キーにする必要があります(例を下に示します)。
- イ: 誤
- 1対多の場合、多側が外部キーを持つべきです。選択肢は「列 b をA表に追加して外部キーにする」としており、これは多側に外部キーを置くべきという原則に反します(多側が B 表なら B に a を置くべき)。よって誤りです。
- ウ: 誤
- 多対多の場合は新しい中間表(結合表)を作成し、両方の主キー(a と b)の双方を外部キーとして持たせる必要があります。選択肢は「その表に列 a か列 b のどちらかを外部キーとして設定する」としており、片方だけでは多対多を表現できません。
- エ: 誤
- 多対多の実現方法として、a を B に、b を A にそれぞれ追加する手法は正しくありません。これは片方向の参照を互いに持たせるだけで、多対多の(多数の組合せ)関係を表現・管理することができませんし、データ整合性・重複管理が困難になります。多対多には中間表が必要です。
よくある誤解
- 外部キーを置けば自動的に1対1になると考える
- 実務では外部キーが参照整合性(参照先が存在すること)を保証するだけで、1対1(1行しか参照されない)を保証するには UNIQUE や主キー化が必要です。
- どちらに外部キーを置いても「同じ実装コスト」と考える
- 実装上はNULL許容や必須性、参照方向、パフォーマンス、参照回数などにより適切な側が変わります。例えば「必ず存在する」なら NOT NULL を付ける設計が多いなど運用上の差があります。
- 両方に外部キーを置けば安全だと考える
- 両側に相互の主キーを外部キーとして持たせるとデータの矛盾(相互参照の挿入順序や削除時の整合性)を招きやすく、1対1を表現する最良の方法ではありません。
補足コラム
1対1を実装する際の具体的な SQL 例を示します。A 表の主キー a、B 表の主キー b がある場合、B に a を外部キーとして置き、かつ一意性を保証する例:
-- B に a を外部キーとして持ち、1対1を保証する(UNIQUEを付ける)
CREATE TABLE A (
a INT PRIMARY KEY,
...
);
CREATE TABLE B (
b INT PRIMARY KEY,
a INT UNIQUE, -- ここで一意性を保証
FOREIGN KEY (a) REFERENCES A(a)
);
外部キーを主キーにして1対1を表現する例:
-- B の主キー自体を A の主キーを参照する外部キーにする(B の存在が A に一対一で紐付く)
CREATE TABLE B (
a INT PRIMARY KEY, -- A の主キーをそのまま主キーにする
...,
FOREIGN KEY (a) REFERENCES A(a)
);
設計時の判断基準:
- どちらのレコードが「必ず存在する」か(必須なら NOT NULL で扱う)
- 参照頻度や結合の多さ(パフォーマンス上どちらに置くか)
- データモデルの自然性(概念的にどちらが従属か)
- 外部キーの制約(ON DELETE/UPDATE の振る舞い)
FAQ
Q. 1対1なら常に外部キーを主キーにすべきですか?
A. 必須ではありません。FK を主キーにすると1対1であることが強く保証されますが、運用上は FK に UNIQUE を付ける(かつ NOT NULL/NULL を用途に応じて設定する)方法もよく使われます。どちらが適切かは設計方針と運用上の要件次第です。
A. 必須ではありません。FK を主キーにすると1対1であることが強く保証されますが、運用上は FK に UNIQUE を付ける(かつ NOT NULL/NULL を用途に応じて設定する)方法もよく使われます。どちらが適切かは設計方針と運用上の要件次第です。
Q. NULL を許す FK に UNIQUE を付けた場合はどうなりますか?
A. 多くのDB(例:PostgreSQL)はNULLを別扱いとするため、複数行で NULL が許されます。すなわち「NULL を許す UNIQUE FK」は完全な1対1を保証しない場合があります。NULL 許容性は注意して設計してください。
A. 多くのDB(例:PostgreSQL)はNULLを別扱いとするため、複数行で NULL が許されます。すなわち「NULL を許す UNIQUE FK」は完全な1対1を保証しない場合があります。NULL 許容性は注意して設計してください。
Q. 両方の表に相互参照(お互いのPKをFKとして持つ)はダメですか?
A. 原理的には可能ですが、挿入順序や削除時の参照整合性が複雑になりやすく、通常はどちらか一方に FK を置き一意性で1対1を保証する方が簡潔で安全です。
A. 原理的には可能ですが、挿入順序や削除時の参照整合性が複雑になりやすく、通常はどちらか一方に FK を置き一意性で1対1を保証する方が簡潔で安全です。
関連キーワード: リレーショナルデータベース, 外部キー, 一意制約, UNIQUE, 1対1, 1対多, 多対多, 中間表, 正規化

\ せっかくなら /
データベーススペシャリストを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

