応用情報技術者 2012年 秋期 午前2 問27
問題文
顧客は一般に複数の銀行に預金するものとして、顧客と銀行の関連を、E-R 図で次のように表現する。このモデルを関係データベース上に “銀行” 表、“口座” 表、“顧客”表として実装する場合の記述として、適切なものはどれか。

選択肢
ア:“銀行”表から “口座” 表への対応関係は多対1である。
イ:“銀行” 表中に参照制約を課した外部キーがある。
ウ:“口座”表から “顧客” 表への対応関係は1対多である。
エ:“口座”表には二つ以上の外部キーがある。(正解)
🔒 解説は解答すると表示されます
中間表による多対多実装【午前2解説】
正解の理由
図は「銀行」と「顧客」を結ぶ関係として「口座」を表す関係(連関)を示しています。顧客は一般に複数の銀行に預金でき、かつ一つの銀行には多数の口座が存在し得るため、銀行と顧客のあいだは多対多の関係になります。リレーショナルデータベースで多対多を実装するには、その多対多関係を表す「口座」表(アソシエイティブエンティティ)を用意し、両端のエンティティを参照する外部キーを持たせます。したがって、正しい記述は エ の「口座表には二つ以上の外部キーがある」です。
(関係の向きについて明確にすると、銀行→口座は1対多(1つの銀行に複数の口座がある)、口座→銀行は多対1(各口座は1つの銀行に属する)という点を前提に説明しています。)
解法ステップ
- 図を解釈する:ひし形「口座」が銀行と顧客を結ぶ関係であり、両側に複数性(m, n)が示されていることを確認する。
- 多対多の判定:両側に「複数」を許す指定があるなら、銀行—顧客は多対多の関係であると判断する。
- 関係から表設計へ:多対多は中間となる関係表(ここでは「口座」表)で解消し、その表に両側エンティティを参照する外部キーを持たせる。
- 選択肢を検証:外部キーの所在と多対多/1対多の表現が選択肢と一致するかを照合する。
選択肢別の誤答解説
- ア: “銀行”表から “口座” 表への対応関係は多対1である。
誤り。正しくは「銀行→口座は1対多(1つの銀行に複数の口座)」です。表記の向き(どちらが親か)を混同すると自己矛盾が生じます。 - イ: “銀行” 表中に参照制約を課した外部キーがある。
誤り。参照制約を課す外部キーは「口座」表の側に置かれます。銀行表は通常は主キー(銀行ID)を持ち、他表から参照される側です。 - ウ: “口座”表から “顧客” 表への対応関係は1対多である。
誤り。口座→顧客は多対1が通常の読み方(各口座は1人の顧客に属する想定)であり、顧客→口座が1対多(顧客は複数口座を持つ)。選択肢の向きが逆になっています。 - エ: “口座”表には二つ以上の外部キーがある。
正しい。口座表は銀行と顧客の双方を参照する外部キー(例: bank_id, customer_id)を持ち、これにより多対多関係が実装されます。
よくある誤解
- 「多対1」と「1対多」を混同する:図中の記述はどちらの方向に対しての多さかを明確に読む必要があります。例えば「銀行→口座は1対多、口座→銀行は多対1」と読み替えます。
- 外部キーは必ず親側に置くと思い込む:外部キーは参照される側(親)ではなく、参照する側(子)に置きます。多対多では中間表が子となり両側を参照します。
- 口座を属性扱いする誤り:連関(口座)が属性ではなく、銀行と顧客をつなぐ独立したエンティティ(アソシエイティブエンティティ)として設計する必要があります。
補足コラム
- 口座表の主キー設計:口座IDのようなサロゲートキーを採るか、(bank_id, customer_id, 口座番号) のような複合キーにするかは要件次第です。複数の口座を同一顧客と銀行の組合せで扱うならサロゲートキーを使う方が柔軟です。
- ジョイントアカウント(共同名義)を扱う場合:口座に複数の顧客が紐づくなら、口座と顧客の間も多対多になり、さらに別の中間表(口座保有者表 account_holders)を設ける設計が必要です。
- 参照制約(外部キー制約)はデータ整合性の要です。削除・更新時のカスケードや制約違反をどう扱うかは業務ルールで決めます。
SQL設計例(単純モデル):
CREATE TABLE bank (
bank_id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
CREATE TABLE customer (
customer_id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
CREATE TABLE account (
account_id SERIAL PRIMARY KEY,
bank_id INTEGER NOT NULL REFERENCES bank(bank_id),
customer_id INTEGER NOT NULL REFERENCES customer(customer_id),
account_no VARCHAR(32) NOT NULL,
balance DECIMAL(15,2) DEFAULT 0
-- 必要に応じて UNIQUE (bank_id, account_no) などを追加
);
FAQ
Q: 口座表に外部キーが2つあると何が便利ですか?
A: 銀行と顧客の両方を明示的に関連付けられるため、どの銀行のどの顧客の口座かを効率よく検索・制約管理できます。多対多関係を1対多に分解し、参照整合性を保てます。
A: 銀行と顧客の両方を明示的に関連付けられるため、どの銀行のどの顧客の口座かを効率よく検索・制約管理できます。多対多関係を1対多に分解し、参照整合性を保てます。
Q: 共同名義の口座はどう表現するのが良いですか?
A: 口座と顧客の間をさらに多対多にする中間テーブル(口座保有者)を作成し、account_id と customer_id を紐づけます。これにより一つの口座に複数顧客を関連付けられます。
A: 口座と顧客の間をさらに多対多にする中間テーブル(口座保有者)を作成し、account_id と customer_id を紐づけます。これにより一つの口座に複数顧客を関連付けられます。
Q: 中間表に属性(例えば口座開設日)を持たせても良いですか?
A: はい。中間表(口座表)が実体としての属性(開設日、残高、口座種別など)を持つのは一般的です。
A: はい。中間表(口座表)が実体としての属性(開設日、残高、口座種別など)を持つのは一般的です。
関連キーワード: E-R図、多対多、アソシエイティブエンティティ、外部キー、関係スキーマ、正規化、参照制約

\ せっかくなら /
応用情報技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

