応用情報技術者 2013年 春期 午前2 問28
問題文
“プログラマは全て社員であり、社員の約10%を占める。社員は社員番号と氏名をもち、職種がプログラマである場合は、使用できるプログラム言語を一つ以上もつ。”という状況を記録するデータベース設計案として、適切なものはどれか。ここで、実線の下線は主キーを、破線の下線は外部キーを表す。
選択肢
ア:社員(社員番号、氏名、職種、プログラム言語)
イ:社員(社員番号、氏名、プログラム言語)
ウ:社員(社員番号、氏名)
プログラマ(社員番号、プログラム言語)
エ:社員(社員番号、氏名)
プログラマ(社員番号、プログラム言語)(正解)
🔒 解説は解答すると表示されます
部分集合化と複合主キー【午前2解説】
正解の理由
設問の要件は「プログラマは社員の部分集合であり、プログラマは使用できるプログラム言語を1つ以上持つ」という点です。共通情報(社員番号、氏名)は社員表に、職種がプログラマの場合の「言語」は別表に切り分けるのが適切です。選択肢のうち エ は社員情報とプログラマ情報を別表に分け、プログラマ表が社員表の社員番号を参照する構成になっています。実装上はプログラマ表で「社員番号とプログラム言語を組にした複合主キー(またはそれに相当する一意制約)」を設定することで、1人が複数言語を持てることを表現できます。したがって、要件を満たすのは エ です。
(重要)プログラム言語だけを単独で主キーにする設計は誤りです。同じ言語を複数人が持つ場合や、1人が複数言語を持つ場合を表現できないため、実務ではプログラマ表を (社員番号, プログラム言語) の複合主キーにするか、社員番号を外部キーとして言語ごとに1レコードを持たせ、一意制約で重複を防ぎます。
解法ステップ
- 要件を整理する
- 「プログラマは全て社員」→ サブタイプ(部分集合)関係。社員表がスーパタイプ。
- 「プログラマはプログラム言語を1つ以上持つ」→ 多値属性(1対多)。
- データモデルの原則を適用する
- スーパタイプの共通属性は社員表へ。サブタイプ固有の多値属性(言語)は別表へ切り出す。
- 主キー・外部キーを決める
- 社員表は社員番号を主キー。プログラマ表は社員番号を外部キーとして持ち、(社員番号, プログラム言語)を複合主キーもしくは一意にする制約を付与して多値を表現する。
- 選択肢と照合して最も要件と設計原則に合うものを選ぶ。
選択肢別の誤答解説
-
ア: 社員(社員番号、氏名、職種、プログラム言語)
- 問題点:プログラム言語を社員表の単一属性にしているため、プログラマ以外の社員はNULLが発生するか、1人が複数言語を持てない。多値属性を表現できないため不適切。
-
イ: 社員(社員番号、氏名、プログラム言語)
- 問題点:職種情報がなくプログラマかどうか判別できない上、言語が社員表の単一属性になっているため多値を表現できない。要件を満たさない。
-
ウ: 社員(社員番号、氏名)
プログラマ(社員番号、プログラム言語)- 問題点:プログラマ表に主キーが明示されていない(重複防止の一意性が不明)ため、同一組(社員番号+言語)の重複を防げない仕様と解釈される。実運用では一意制約あるいは複合主キーが必要であり、表記が不足しているため不適切。
-
エ: 社員(社員番号、氏名)
プログラマ(社員番号、プログラム言語)- 本選択肢は社員とプログラマを分け、プログラマ表が社員番号を参照する構成である点が要件と整合します。実装時には「社員番号+プログラム言語」を複合主キー(またはこれに相当する一意制約)として扱うことで、1人が複数言語を持てる要件を正しく満たします。したがって本問の最良解は エ です。
よくある誤解
- 「プログラム言語を主キーにすればよい」
- 誤り:同一言語を複数の社員が使えるので言語単独では主キーにならない。主キーはレコードを一意に識別できなければならない。
- 「多値属性は1つの列にカンマ区切りで入れてよい」
- 誤り:正規化に反し検索性・整合性が悪化する。言語は別表に分ける。
- 「サブタイプの属性は全部スーパタイプに入れるべき」
- 誤り:サブタイプ属性はサブタイプ表に切り出すのが原則(サブタイプでしか意味を持たない属性をスーパタイプに置くとNULLが多発する)。
補足コラム
実装例(SQL, 推奨パターン:複合主キーによる多値表現):
CREATE TABLE 社員 (
社員番号 INT PRIMARY KEY,
氏名 VARCHAR(100),
職種 VARCHAR(50) -- 例: 'プログラマ' 等
);
CREATE TABLE プログラマ言語 (
社員番号 INT,
プログラム言語 VARCHAR(50),
PRIMARY KEY (社員番号, プログラム言語),
FOREIGN KEY (社員番号) REFERENCES 社員(社員番号)
);
代替案として、プログラマ言語に一意のID(surrogate key)を付け、(社員番号, 言語) にユニーク制約を設ける方法もあります。どちらもデータの一貫性(参照整合性、一意性)を保つことが目的です。
FAQ
Q1: 「社員が1人もプログラマでない場合、プログラマ表は空でもよいか?」
A1: はい。プログラマは社員の部分集合なので、該当者がいなければプログラマ表は空になります。参照整合性に問題がないことを確認してください。
A1: はい。プログラマは社員の部分集合なので、該当者がいなければプログラマ表は空になります。参照整合性に問題がないことを確認してください。
Q2: 「同じ社員が同じ言語を誤って二重に登録するのを防ぐには?」
A2: プログラマ表に (社員番号, プログラム言語) の複合主キーまたは一意制約を設定すれば防げます。
A2: プログラマ表に (社員番号, プログラム言語) の複合主キーまたは一意制約を設定すれば防げます。
Q3: 「職種が変わったときの扱いは?」
A3: 職種がプログラマでなくなった場合、プログラマ表の対応する行は削除する(または無効化する)運用が一般的です。運用ルールと参照整合性制約の設計を合わせてください。
A3: 職種がプログラマでなくなった場合、プログラマ表の対応する行は削除する(または無効化する)運用が一般的です。運用ルールと参照整合性制約の設計を合わせてください。
関連キーワード: リレーショナルデータベース、正規化、部分集合化、サブタイプ、外部キー、複合主キー、参照整合性、E-Rモデリング、多値属性

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

