応用情報技術者 2021年 秋期 午前2 問28
問題文
受注入力システムによって作成される次の表に関する記述のうち、適切なものはどれか。受注番号は受注ごとに新たに発行される番号であり、項番は1回の受注で商品コード別に連番で発行される番号である。
なお、単価は商品コードによって一意に定まる。

選択肢
ア:第1正規形でない。
イ:第1正規形であるが第2正規形でない。(正解)
ウ:第2正規形であるが第3正規形でない。
エ:第3正規形である。
🔒 解説は解答すると表示されます
関数従属性と正規化【午前2解説】
正解の理由
この表は各セルが単一値なので第1正規形(1NF)を満たします。しかし、主キーを(受注番号, 項番)と見ると、受注番号だけで受注日や得意先コードが一意に定まるため、これらは主キーの一部にのみ依存する「部分従属」が生じます。また、単価は商品コードによって一意に定まるので、(受注番号, 項番) → 商品コード と 商品コード → 単価 により単価が主キーに対して推移的に従属します。したがって、第2正規形(2NF)を満たさず、結果として第3正規形(3NF)も満たしません。以上より、本問の正しい選択肢は イ です。
(重要な関数従属性の表記)
- 受注番号 → 受注日, 得意先コード
- (受注番号, 項番) → 商品コード, 数量, …
- 商品コード → 単価
※上の向きは「決定する側 → 従属する側」を示しています。
解法ステップ
- 主キー候補を見つける
- 項番は「1回の受注で商品コード別に連番」とあるため、1行を一意に特定するには受注番号と項番の組合せ、すなわち (受注番号, 項番) が主キーになると判断する。
- 関数従属性を列挙する
- 受注番号だけで受注日や得意先コードが定まる(同一受注で複数行にわたって同じ日付・得意先が繰り返されている)ため、受注番号 → 受注日, 得意先コード。
- 商品コードは各行で与えられ、商品コード → 単価(問題文に明記)となる。
- 主キーから商品コード・数量などが決まる: (受注番号, 項番) → 商品コード, 数量。
- 各正規形の条件を順に確認する
- 1NF:各セルが原子値であるため満たす。
- 2NF:主キーが複合キーのとき、その一部に依存する非キー属性があれば違反。ここでは受注番号 → 受注日・得意先コードがあるので違反。よって2NFではない。
- 3NF:2NFを満たしていないため問わないが、商品コード → 単価 により推移従属も生じるため3NFも満たさない。
選択肢別の誤答解説
- ア: 「第1正規形でない。」
誤り。各項目は単一値(原子値)で格納されており、1NF の要件を満たしている。 - イ: 「第1正規形であるが第2正規形でない。」
正しい。上記の通り、受注番号による部分従属があるため2NFを満たさない。 - ウ: 「第2正規形であるが第3正規形でない。」
誤り。2NF を満たすためには部分従属がないことが必要だが、本表は受注番号 → 受注日等の部分従属があるため最初から2NFではない。 - エ: 「第3正規形である。」
誤り。部分従属および商品コード→単価 による推移従属があるため、3NF の条件も満たさない。
よくある誤解
- 関数従属性の矢印を逆に書く(例:受注日 → 受注番号 と誤表記)
→ 依存関係の向きを誤ると「部分従属/推移従属」の判定を誤るので注意する。 - 「商品コード→単価」を見ているだけで2NFの判定を誤る
→ 商品コード→単価 は推移従属の原因になり得るが、まず部分従属(受注番号 → 受注日等)があるかを確認すること。 - 項番や商品コードを主キーの一部と誤認する
→ 問題文の説明(項番は受注ごとの連番)から、主キーが (受注番号, 項番) である点を見落とさない。
補足コラム
正規化の実務的な分割例(設計方針):
- 受注(Orders)テーブル:受注番号(PK) → 受注日, 得意先コード
- 明細(OrderLines)テーブル:受注番号, 項番(PK) → 商品コード, 数量
- 商品(Products)テーブル:商品コード(PK) → 単価
例(SQL):
CREATE TABLE Orders (
order_no CHAR(6) PRIMARY KEY,
order_date DATE,
customer_code CHAR(4)
);
CREATE TABLE OrderLines (
order_no CHAR(6),
line_no INT,
product_code CHAR(5),
qty INT,
PRIMARY KEY (order_no, line_no),
FOREIGN KEY (order_no) REFERENCES Orders(order_no),
FOREIGN KEY (product_code) REFERENCES Products(product_code)
);
CREATE TABLE Products (
product_code CHAR(5) PRIMARY KEY,
unit_price INT
);
この分割により、部分従属と推移従属を解消して 3NF に近づけられます。
FAQ
Q1: 主キーが (受注番号, 項番) であることが確実か?
A1: 問題文で「項番は1回の受注で商品コード別に連番」とあるため、同一受注内で行を一意に識別するには受注番号と項番の組合せが必要であり、これが自然な主キー候補です。
A1: 問題文で「項番は1回の受注で商品コード別に連番」とあるため、同一受注内で行を一意に識別するには受注番号と項番の組合せが必要であり、これが自然な主キー候補です。
Q2: 商品コード → 単価 があるなら単に商品コードをキーにすればよいのでは?
A2: 取引データ(受注明細)では、どの受注のどの行かを識別するために明細側に受注番号と行番号が必要であり、商品情報は別テーブルに分離して参照するのが適切です。
A2: 取引データ(受注明細)では、どの受注のどの行かを識別するために明細側に受注番号と行番号が必要であり、商品情報は別テーブルに分離して参照するのが適切です。
Q3: 1NF, 2NF, 3NF の判定での優先順位は?
A3: 下位の正規形(1NF)が満たされていることを確認した上で、2NF→3NF の順に条件を確認します。特に複合キーがある場合は部分従属のチェックが重要です。
A3: 下位の正規形(1NF)が満たされていることを確認した上で、2NF→3NF の順に条件を確認します。特に複合キーがある場合は部分従属のチェックが重要です。
関連キーワード: 正規化, 関数従属性, 第1正規形, 第2正規形, 第3正規形, 主キー, 部分従属, 推移従属, テーブル分割

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

