基本情報技術者 2010年 秋期 午前(科目A) 問29
問題文
次の“受注台帳”表を“注文”表と“顧客”表に分解し、第3正規形にしたとき、両方に必要な属性はどれか。ここで、送付先と支払方法は注文ごとに決めるものとする。また、表の下線は主キーを表す。
受注台帳(注文番号, 注文年月日, 顧客ID, 顧客名, 顧客住所, 品目, 数量, 送付先, 支払方法, 受注金額)
選択肢
ア:顧客ID(正解)
イ:顧客名
ウ:支払方法
エ:注文番号
受注台帳を第3正規形に分解する問題【午前2 解説】
要点まとめ
- 結論: 両方に必要なのは顧客IDです。顧客表の主キーで顧客を一意に識別し、注文表では外部キーとして注文と顧客を結び付けるため必須です。
- 根拠: 第3正規形では属性はその表の主キーにのみ従属させ、転置的従属を排除します。顧客名や住所は顧客に属し、送付先・支払方法は注文ごとに決まるため分離します。
- 差がつくポイント: 顧客名を両方に冗長に持たないこと、支払方法は注文属性に残すこと、注文番号は注文表の主キーのみとする点を正確に理解してください。
正解の理由
顧客IDは「顧客」エンティティを一意に識別する主キーになるため、顧客表に格納されます。一方で「注文」表はどの顧客がその注文を出したかを示す必要があるので、顧客IDを外部キーとして持ちます。これにより注文と顧客の関係が明確に保たれ、顧客名や住所のような顧客に固有の属性を重複して持たずに済みます。送付先や支払方法は「注文ごとに決める」属性なので注文表に残し、注文番号は注文表の主キーであり顧客表には不要です。以上より、両方に必要な属性は顧客ID(選択肢ア)です。
よくある誤解
- 顧客名を両方に入れるべきと考える: 見かけ上便利でも冗長性・更新異常の原因になるためNGです。
- 支払方法を顧客属性だと誤認する: 問題文に「注文ごとに決める」と明記されている場合は顧客に紐づけてはいけません。
- 注文番号を顧客表にも必要と考える: 注文番号は注文の主キーであり顧客の属性ではないため顧客表には含めません。
解法ステップ
- 表の属性を読んで「エンティティ候補」を洗い出す(ここでは「顧客」と「注文」)。
- 各エンティティの主キーを決める(顧客→顧客ID、注文→注文番号)。
- 各属性がどちらの主キーに従属するか判定する(顧客名・住所→顧客、送付先・支払方法・受注金額・品目・数量・注文年月日→注文)。
- 第1〜第3正規形の基準で部分従属や転置的従属を排除する(顧客名等を顧客表へ移す、顧客IDを注文表へ外部キーとして残す)。
- 最終確認:冗長性がなく、各非キー属性がそのキーに直接従属しているか確認する。
選択肢別の誤答解説
- ア: 顧客ID — 正解。顧客表の主キーであり、注文表では外部キーとして両方に存在する必要があります。
- イ: 顧客名 — 誤り。顧客名は顧客表に属する属性で、注文表に複製すると冗長性と更新不整合の原因になります。
- ウ: 支払方法 — 誤り。問題文で「注文ごとに決める」とあり、注文表側の属性であって顧客表に共通して持たせるものではありません。
- エ: 注文番号 — 誤り。注文番号は注文表の主キーであり、顧客表に含めるべき属性ではありません。顧客側の主キーは顧客IDです。
補足コラム
- 第3正規形(3NF)のポイントは「各非キー属性が主キーに対してのみ直接従属している」ことです。転置的従属(非キー→非キー)を排除することで更新・挿入・削除の異常を防げます。
- 実務ではパフォーマンスや運用上の理由で、正規化を部分的に緩め(デノーマライズ)ることがありますが、その場合は冗長性と整合性確保手段(更新処理、制約、トリガ)を設計する必要があります。
- 例: SQLでのテーブル定義(参考)
CREATE TABLE Customer ( customer_id VARCHAR(20) PRIMARY KEY, customer_name VARCHAR(100), address VARCHAR(200) ); CREATE TABLE OrderHead ( order_no VARCHAR(20) PRIMARY KEY, order_date DATE, customer_id VARCHAR(20), ship_to VARCHAR(200), payment_method VARCHAR(50), total_amount DECIMAL(10,2), FOREIGN KEY (customer_id) REFERENCES Customer(customer_id) );
FAQ
Q1: 顧客名を注文表に入れると何が具体的に問題ですか?
A1: 顧客名が変更された場合に注文表の同じ顧客名を更新する必要が生じ、更新漏れによる不整合(更新異常)が発生します。ID参照にすれば一箇所の更新で済みます。
A1: 顧客名が変更された場合に注文表の同じ顧客名を更新する必要が生じ、更新漏れによる不整合(更新異常)が発生します。ID参照にすれば一箇所の更新で済みます。
Q2: 送付先が顧客の「主な住所」として固定ならどうしますか?
A2: 問題文の条件次第ですが、送付先が「注文ごとに決める」なら注文属性です。顧客の主な住所として固定なら顧客表に持たせ、別に配送先テーブルを設けるのが柔軟です。
A2: 問題文の条件次第ですが、送付先が「注文ごとに決める」なら注文属性です。顧客の主な住所として固定なら顧客表に持たせ、別に配送先テーブルを設けるのが柔軟です。
Q3: 注文明細(品目・数量)はどう分けるべきですか?
A3: 注文ごとに複数品目が存在する場合は注文ヘッダ表(OrderHead)と明細表(OrderLine)に分け、明細側に品目・数量を持たせます。これが正しいリレーション設計です。
A3: 注文ごとに複数品目が存在する場合は注文ヘッダ表(OrderHead)と明細表(OrderLine)に分け、明細側に品目・数量を持たせます。これが正しいリレーション設計です。
関連キーワード: 正規化、第3正規形(3NF)、主キー、外部キー、リレーショナル設計、受注管理、ER図、データ冗長性、更新異常、デノーマライズ

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

