応用情報技術者 2020年 秋期 午前2 問28
問題文
関係 “注文記録”の属性間に①〜⑥の関数従属性があり、それに基づいて第3正規形まで正規化を行って、“商品”、“顧客”、“注文”、“注文明細”の各関係に分解した。関係“注文明細” として、適切なものはどれか。ここで、{X, Y) は、属性XとYの組みを表し、X→Yは、XがYを関数的に決定することを表す。また、実線の下線は主キーを表す。
注文記録 (注文番号、注文日、顧客番号、顧客名、商品番号、商品名、数量、販売単価)
〔関数従属性〕
① 注文番号 → 注文日 ② 注文番号 → 顧客番号
③ 顧客番号 → 顧客名 ④ {注文番号、商品番号} → 数量
⑤(注文番号、商品番号)→ 販売単価 ⑥ 商品番号 → 商品名
選択肢
ア:注文明細(注文番号、顧客番号、商品番号、顧客名、数量、販売単価)
イ:注文明細(注文番号、顧客番号、数量、販売単価)
ウ:注文明細(注文番号、商品番号、数量、販売単価)(正解)
エ:注文明細(注文番号、数量、販売単価)
🔒 解説は解答すると表示されます
注文明細の正規化【午前2解説】
正解の理由
関係“注文明細”は各注文の個々の商品ごとの明細を表すため、行を一意に識別する主キーは注文と商品を合わせた複合キーになります。与えられた関数従属性から、 が数量および販売単価を関数的に決定する(④, ⑤)ため、注文明細に含めるべき属性は主キーとしての注文番号と商品番号、およびそれらに従属する数量と販売単価です。したがって選択肢の中で正しいのは ウ です。
(補足)顧客情報や商品名はそれぞれ別のキーで決まるので、注文明細に含めると冗長になり正規化の目的に反します。
解法ステップ
- 与えられた関数従属性を整理する。主なものは
- (①, ②)
- (③)
- (⑥)
- (④, ⑤)
- 注文明細として必要な主キーを決める。行(=1件の注文に含まれるある商品の数量)を一意に特定するには注文番号と商品番号の組が必要で、これが最小の候補キーである。
- 主キーに対して直接従属する属性を注文明細に残す。④, ⑤より数量と販売単価は に従属するため注文明細に含める。
- 商品名・顧客名・顧客番号・注文日は、それぞれ別関係(商品・顧客・注文)で管理し、参照キーで接続する(冗長化を避ける)。
選択肢別の誤答解説
- ア: 注文明細(注文番号、顧客番号、商品番号、顧客名、数量、販売単価)
問題点は二つあります。まず (②)があるため、顧客番号を主キーの一部として含めるとキーの最小性が失われている(同じ注文番号から顧客番号が決定できるため、複合キーは冗長)。さらに顧客名は (③)により顧客番号に依存するため、顧客名は主キーの一部に依存している状態になります。これは「部分関数従属」に該当し、2NF を満たさない(冗長性と更新異常を招く)。したがって不適切です。
(ここで注意:顧客名の依存が「推移的関数従属」と誤って説明されることがあるが、本ケースでは顧客名が主キーの一部に直接依存しているため「部分関数従属」と区別されます。) - イ: 注文明細(注文番号、顧客番号、数量、販売単価)
商品番号が含まれておらず、同一注文内で複数の商品がある場合に各行を一意に識別できません。主キーとしても不十分であり、注文明細の粒度に合いません。 - ウ: 注文明細(注文番号、商品番号、数量、販売単価)
正解。 が主キーとなり、数量・販売単価はこの主キーに直接従属するので第3正規形に適合します。商品名や顧客情報は別関係で管理します。 - エ: 注文明細(注文番号、数量、販売単価)
商品番号が抜けているため、1つの注文で複数商品を扱えず、明細を表す構造として不十分です。
よくある誤解
- 「顧客名は注文番号に推移的に依存している」と説明してしまう誤り
顧客名は顧客番号に直接依存しており、選択肢アのように顧客番号が主キーの一部になっていると顧客名は主キーの一部に依存する(部分関数従属)という点を取り違えないこと。推移的従属は「キー→非キーA、非キーA→非キーB」の形で生じる場合に言う。 - 販売単価は常に商品番号で決まると思い込む誤解
問題文の FD では販売単価は に依存している(⑤)。これにより、同じ商品でも注文ごとに単価が異なり得る(割引やキャンペーン等)ことが示唆されるため、商品テーブルに販売単価を置くのは誤りの場合がある。
補足コラム
正規化を行う際の実務的観点として、必ずしも「すべてを厳密に第3正規形にする」ことが最良とは限りません。検索性能や結合回数、更新頻度など運用面でのトレードオフにより一部冗長化(デノーマライゼーション)を採ることがあります。ただし試験問題では与えられた関数従属性に基づく理論的正規化(第3正規形到達)を問うため、ここで示したように冗長性を排した分解が正解になります。
FAQ
Q1: なぜ顧客番号を注文明細に持たせてはいけないのですか?
A1: 注文明細に顧客番号を持つと、顧客番号が注文番号から決まる()ためキーの最小性が失われ冗長が生じます。顧客情報は注文(注文ヘッダ)に持たせ、注文明細は注文番号を外部キーとして参照する構成が自然です。
A1: 注文明細に顧客番号を持つと、顧客番号が注文番号から決まる()ためキーの最小性が失われ冗長が生じます。顧客情報は注文(注文ヘッダ)に持たせ、注文明細は注文番号を外部キーとして参照する構成が自然です。
Q2: 販売単価が商品番号で決まらない場合とは?
A2: 販売単価が に依存するということは、商品の単価が注文ごとに変わる可能性(割引、価格改定、特売など)があることを意味します。従って販売単価は注文明細に置くべきです。
A2: 販売単価が に依存するということは、商品の単価が注文ごとに変わる可能性(割引、価格改定、特売など)があることを意味します。従って販売単価は注文明細に置くべきです。
Q3: 「部分関数従属」と「推移的関数従属」の見分け方は?
A3: 部分関数従属は「複合キーの一部→非キー」の形で、非キー属性がキーの一部にのみ依存している場合。推移的関数従属は「キー→非キーA、非キーA→非キーB」という連鎖で、非キーBがキーに対して非キーAを経由して依存する場合です。解答ではどの属性がキー(あるいはキーの一部)かを明確にして判定します。
A3: 部分関数従属は「複合キーの一部→非キー」の形で、非キー属性がキーの一部にのみ依存している場合。推移的関数従属は「キー→非キーA、非キーA→非キーB」という連鎖で、非キーBがキーに対して非キーAを経由して依存する場合です。解答ではどの属性がキー(あるいはキーの一部)かを明確にして判定します。
関連キーワード: 関数従属性、第3正規形、部分関数従属、主キー設計、リレーショナル正規化、注文明細、データベース設計

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

