データベーススペシャリスト 2015年 午前2 問06
問題文
受注入力システムによって作成される次の表に関する記述のうち、適切なものはどれか。受注番号は受注ごとに新たに発行される番号であり、項番は1回の受注で商品コード別に連番で発行される番号である。
なお、単価は商品コードによって一意に定まる。

選択肢
ア:正規化は行われていない。
イ:第1正規形まで正規化されている。(正解)
ウ:第2正規形まで正規化されている。
エ:第3正規形まで正規化されている。
🔒 解説は解答すると表示されます
第1正規形の判定【午前2解説】
正解の理由
表は各列が原子値であり繰り返しグループもないため第1正規形の要件を満たしています。一方、主キーを正しく定義すると、項番は「1回の受注で商品コード別に連番で発行される」とあるため、行を一意に識別するには少なくとも受注番号と商品コードが必要になります(最小限には受注番号+商品コード+項番の組合せが主キーとなる)。その結果、単価は「商品コードによって一意に定まる」と明示されているため、単価は主キーの一部(商品コード)にのみ依存する部分関数従属が生じます。部分関数従属があると第2正規形を満たさないため、本表は第1正規形までであり、選択肢の中では イ が適切です。
解法ステップ
- 主キー候補を決める
- 設問文の「項番は1回の受注で商品コード別に連番で発行される」を読み、同じ項番値が異なる商品コードで使われうる点を考慮する。したがって行の一意性を保証するには受注番号に加えて商品コード(および項番)が必要。主キーを (受注番号, 商品コード, 項番) とするのが妥当。
- 第1正規形の判定
- 各フィールドが原子値であり、列に複数値や繰り返しグループがないかを確認。これにより第1正規形を満たしていると判定。
- 第2正規形の判定(部分関数従属の検査)
- 非キー属性(受注日、得意先コード、単価、数量 等)が主キーの一部にのみ依存していないかを確認。受注日・得意先コードは受注番号だけで決まり、単価は商品コードだけで決まるため、主キーの部分に依存する属性が存在する=第2正規形を満たさない。
- 第3正規形の判定
- 第2正規形を満たしていないため第3正規形も満たさない(第3正規形は第2正規形を前提とする)。
選択肢別の誤答解説
- ア: 正規化は行われていない。
誤り。表は各列が原子値で定義され、繰り返しカラムもないため第1正規形までは満たしている。よって「正規化は行われていない」は不適切。 - イ: 第1正規形まで正規化されている。
正しい。上記の通り第1正規形は満たすが、主キーの一部に依存する属性(部分関数従属)が存在するため第2正規形以降は満たさない。 - ウ: 第2正規形まで正規化されている。
誤り。受注日や得意先コードは受注番号にのみ依存し、単価は商品コードにのみ依存するため、これらは主キーの「一部」に依存する部分関数従属であり、第2正規形の要件を満たさない。 - エ: 第3正規形まで正規化されている。
誤り。第3正規形は第2正規形を満たしたうえで推移的従属がないことが必要だが、そもそも第2正規形を満たしていないため第3正規形も満たさない。
よくある誤解
- 項番だけで主キーが決まる、または主キーは受注番号+項番だと誤解する
- 項番が「商品コード別に連番」と明示されている点を見落とし、受注番号+項番だけで一意と誤認するケースが多い。設問の記述を正しく解釈して商品コードをキーに含めることが重要です。
- 単価が「行ごとに固定の値」だから主キー全体に依存すると考える
- 単価は商品コードで一意に定まるため、主キーの一部(商品コード)に依存する。依存先が主キーの一部か全部かを見分ける観察が必要です。
- 1NFと2NF/3NFの違いを混同する
- 1NFはデータの原子性・繰り返し禁止の要件、2NFは「複合主キーの場合、非キー属性が主キーの全体に完全関数従属していること」を要求する点を押さえてください。
補足コラム
第2正規形へ改善するには、部分関数従属を解消するための分離(分割)が必要です。典型的な分解例は次のとおりです。
- 受注ヘッダ(Orders): (受注番号 PK, 受注日, 得意先コード, …)
- 受注番号が主キーで、受注レベル属性を保持
- 受注明細(OrderItems): (受注番号, 商品コード, 項番 PK候補, 数量, …)
- 明細の主体を保持し、数量などは明細に属する
- 商品マスタ(Products): (商品コード PK, 単価, …)
- 単価は商品コードで決まるため商品マスタに移動
この分解により、単価は商品コードに属する属性となり部分従属が解消され、第2正規形を満たす形になります(さらに必要なら第3正規形の検討を行います)。
例(SQLスキーマのイメージ)
CREATE TABLE Orders (
order_no VARCHAR PRIMARY KEY,
order_date DATE,
customer_code VARCHAR
);
CREATE TABLE Products (
product_code VARCHAR PRIMARY KEY,
unit_price INTEGER
);
CREATE TABLE OrderItems (
order_no VARCHAR,
product_code VARCHAR,
line_no INTEGER,
quantity INTEGER,
PRIMARY KEY (order_no, product_code, line_no),
FOREIGN KEY (order_no) REFERENCES Orders(order_no),
FOREIGN KEY (product_code) REFERENCES Products(product_code)
);
FAQ
Q1: 項番の記述がやや分かりにくい場合、どう判断すればよいですか?
A1: 「商品コード別に連番で発行される」という文言があれば、同一受注内で同じ項番が異なる商品コードに対して使われうることを意味します。したがって、主キーに商品コードを含める必要があると判断してください。
A1: 「商品コード別に連番で発行される」という文言があれば、同一受注内で同じ項番が異なる商品コードに対して使われうることを意味します。したがって、主キーに商品コードを含める必要があると判断してください。
Q2: 部分関数従属と推移的従属の見分け方は?
A2: 部分関数従属は「複合主キーの一部にのみ依存する」場合。推移的従属は「非キー属性Aが別の非キー属性Bを介して主キーに依存する」場合(主キー → B → A)。第2正規形は部分従属を排除、第3正規形は推移的従属を排除します。
A2: 部分関数従属は「複合主キーの一部にのみ依存する」場合。推移的従属は「非キー属性Aが別の非キー属性Bを介して主キーに依存する」場合(主キー → B → A)。第2正規形は部分従属を排除、第3正規形は推移的従属を排除します。
Q3: 今回の表で数量はどのキーに依存しますか?
A3: 数量は明細行の属性であり、行を一意に識別する主キー(受注番号+商品コード+項番)に依存すると考えるのが自然です(したがって数量は部分従属ではなく主キー全体への従属である点に注意)。
A3: 数量は明細行の属性であり、行を一意に識別する主キー(受注番号+商品コード+項番)に依存すると考えるのが自然です(したがって数量は部分従属ではなく主キー全体への従属である点に注意)。
関連キーワード: 正規化、部分関数従属、第一正規形、主キー、商品マスタ

\ せっかくなら /
データベーススペシャリストを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

