データベーススペシャリスト 2015年 午後1 問01
データベースの設計に関する次の記述を読んで、設問1〜3に答えよ。
A社は、書籍の販売を主力事業とする会社である。 A社では現在、インターネット上で書籍を販売する ECサイトの開設を計画しており、システム部のB君がデータベースの設計を行っている。
〔書籍の概要〕
1.書籍
書籍は、単行本 新書 文庫本など、様々な書籍の形態で出版されている。
(1) 書籍作品とは、書籍の形態にかかわらない作品そのものであり、書籍のタイトルなどの属性をもつ。
(2) 形態別書籍とは、書籍作品を様々な書籍の形態で出版したものであり、出版社名、ページ数などの属性をもつ。
(3) 書籍作品には 1 人又は複数の著者が存在し、著者ごとに、主要な著者役割が一つ定められている。
(4) 著者役割とは、著者が著作に関わった際の役割である。 例えば、‘著作者'、*共著者'、'原著者'、'翻訳者'、'監修者' などである。
(5) カテゴリとは、書籍作品の分類である。 カテゴリは階層構造となっており、例えば、情報技術” と “データベース’というカテゴリでは、'データベース'の上位カテゴリが ‘情報技術” である。 書籍作品は、一つ又は複数のカテゴリに属する。
2.販売書籍
書籍のうち、A社のECサイトで購入できる書籍を販売書籍と呼ぶ。 販売書籍は、新品書籍、中古書籍に分類される。
(1) 新品書籍は、形態別書籍ごとに、販売価格、実在庫数、受注残数を記録する。
(2) 中古書籍は、1冊ごとに、販売価格、品質ランク、品質コメント、ステータスを記録する。
(3) 新品書籍が、絶版、重版待ち又は出版社の在庫僅少の場合は、実在庫数を上回る注文を受け付けない。 その他の場合は、実在庫数にかかわらず、注文を受け付ける。
〔会員の概要〕
A社のECサイトを利用して販売書籍を注文するためには、氏名、住所、メールアドレスなどの情報を登録して会員になる必要がある。
(1) 会員は、1回の注文で、新品書籍・中古書籍にかかわらず、複数種類の販売書籍を注文できる。 また、新品書籍については、それぞれ複数冊注文できる。
(2) 出品会員とは、A社の ECサイト上で中古書籍を販売できる会員である。 会員は、仮想店舗名などの情報を追加登録すれば、出品会員になれる。
(3) 出品会員が、ECサイト上で中古書籍を出品するには、販売価格、品質ランク、品質コメントを登録し、中古書籍の現物をA社宛てに送付する。
(4) 会員は、購入した中古書籍が、ECサイトに表示されていた品質ランク、品質コメントどおりであったかなど、出品会員を評価できる。 会員による評価は、会員ごと出品会員ごとに最新の評価だけを記録する。
〔業務の概要〕
1.登録業務
書籍作品、形態別書籍、販売書籍の情報を登録する。
2.入荷業務
販売書籍の入荷を記録し、所定の保管場所に格納する。
3.受注業務
ECサイトで会員からの注文を受け付け、在庫の引当てを行う。 注文日時 注文した書籍のタイトルなどを記載した電子メールを、会員宛てに送付する。
4.出荷業務
(1) 受注した販売書籍を保管場所から取り出し、梱包して出荷する。 出荷日時、出荷した書籍のタイトルなどを記載した電子メールを、会員宛てに送付する。
(2) 出荷時点で同一会員から複数回の注文があった場合、一つにまとめて出荷する。 同一会員からの複数回の注文に、同じ新品書籍が含まれる場合がある。
(3) 出荷時点で出荷対象の新品書籍の在庫が不足していた場合、実在庫数分だけ出荷し、残りは入荷後に出荷する。
〔データモデルの設計〕
B君は、概念データモデル (図1) 及び関係スキーマ (図2) の設計を行った。


図2の関係スキーマの主な属性とその意味 制約を、表1に示す。

〔データベースの更新処理〕
B君は、図2の関係スキーマをテーブルとして実装し、入荷業務、受注業務、出荷業務で行うデータベース更新処理を整理し、表2にまとめた。

解答に当たっては、巻頭の表記ルールに従うこと。
設問1:図2の関係 “書籍作品” について(1)、(2)に答えよ。
(1)関係 “書籍作品” の候補キーを全て答えよ。 また、部分関数従属性、推移的関数従属性の有無を、“あり” 又は “なし” で答えよ。 “あり” の場合は、その関数従属性の具体例を一つ、次の表記法に従って示せ。
なお、候補キー及び表記法に示されている属性1 属性2が複数の属性から構成される場合は、{}でくくること。模範解答
候補キー:{書籍作品ID, 著者ID}
部分関数従属性の有無:あり
部分関数従:
・書籍作品ID → タイトル
・著者ID → 著者名
推移的関数従属性の有無:あり
推移的関数従:
{書籍作品ID, 著者ID } → 著者役割コード → 著者役割名
解説
解答の論理構成
- 属性列挙と意味の確認
「図2」の“書籍作品”は
書籍作品ID / タイトル / 著者ID / 著者名 / 著者役割コード / 著者役割名
で構成される。 - 業務規約による一意性の読み取り
【問題文】「書籍作品には 1 人又は複数の著者が存在し、著者ごとに、主要な著者役割が一つ定められている。」
→ 作品と著者の組が一意であり、著者役割はその結果として決まる。 - 候補キーの決定
作品単体では著者が一意にならず、著者単体でも作品が一意にならない。よって {書籍作品ID, 著者ID} が候補キー。 - 部分関数従属性の判定
- 書籍作品ID → タイトル(作品固有)
- 著者ID → 著者名(著者固有)
どちらもキーの一部だけで決まるため“あり”。
- 推移的関数従属性の判定
- {書籍作品ID, 著者ID} → 著者役割コード(キー全体で決定)
- 著者役割コード → 著者役割名(コードに依存)
したがって {書籍作品ID, 著者ID} → 著者役割コード → 著者役割名 が推移的関数従。“あり”。
誤りやすいポイント
- 「著者役割コードも候補キーに含める」と誤解する
→ 規約で“著者ごとに主要な役割は一つ”と明示。 - 著者名やタイトルの同名問題の読み落とし
→ 【表1】「異なる書籍作品のタイトルが同名である場合がある。」などにより、識別子は ID属性 である点を再確認。 - 部分関数従と推移的関数従を混同する
→ キーの“部分”か“非キー経由”かを整理してメモすると防げる。
FAQ
Q: 著者役割コードを候補キーに入れてはいけない決定的な根拠は?
A: 業務規約に「著者ごとに、主要な著者役割が一つ」とあるため、役割コードはキーに依存する属性であり、キーそのものではありません。
A: 業務規約に「著者ごとに、主要な著者役割が一つ」とあるため、役割コードはキーに依存する属性であり、キーそのものではありません。
Q: 著者ID → 著者役割コード の従属性は存在しないのか?
A: 複数作品で同じ著者が異なる役割を持つ場合があるため、著者ID単独では役割コードを一意に決定できません。したがって従属性は成立しません。
A: 複数作品で同じ著者が異なる役割を持つ場合があるため、著者ID単独では役割コードを一意に決定できません。したがって従属性は成立しません。
Q: 第三正規形にするにはどう分割すべき?
A: “書籍作品”を
A: “書籍作品”を
- 作品‐著者(書籍作品ID, 著者ID, 著者役割コード)
- 作品(書籍作品ID, タイトル)
- 著者(著者ID, 著者名)
- 著者役割(著者役割コード、著者役割名)
に正規化すれば、部分・推移的従属性とも排除できます。
関連キーワード: 関数従属性、正規化、候補キー、部分関数従、推移的関数従
設問1:図2の関係 “書籍作品” について(1)、(2)に答えよ。
(2)関係書籍作品” は、第1正規形、第2正規形、第3正規形のうち、どこまで正規化されているか答えよ。 また、第3正規形でない場合は、第3 正規形に分解し、主キー及び外部キーを明記した関係スキーマを示せ。
模範解答
正規形:第1正規形
関係スキーマ:
著者(著者ID、著者名)
著者役割(著者役割コード、著者役割名)
書籍作品(書籍作品ID、タイトル)
書籍作品著者(著者ID、書籍作品ID、著者役割コード)
解説
解答の論理構成
-
第1正規形確認
【問題文】図2 “書籍作品(書籍作品ID、タイトル、著者ID、著者名、著者役割コード、著者役割名)” は繰り返し属性や複合属性を持たず、各列が単一値なので第1正規形です。 -
第2正規形違反の確認
主キーは複合候補「書籍作品ID」「著者ID」「著者役割コード」です。
ところが “著者名” は【問題文】「著者を一意に識別する文字列」である “著者ID” のみに関数従属します。
同様に “著者役割名” は “著者役割コード” のみに従属します。
これは「部分関数従属」に該当し、第2正規形に違反します。 -
第3正規形違反の確認
部分従属を解消しても、“書籍作品著者” に “著者役割名” を残したままだと
“著者役割コード → 著者役割名” が成立し、主キー以外の列が他の非キー列に従属する「推移的関数従属」が発生します。
よって第3正規形でもありません。 -
分解方針
① “著者ID → 著者名” を独立させて関係 “著者” を作成
② “著者役割コード → 著者役割名” を独立させて関係 “著者役割” を作成
③ “書籍作品ID → タイトル” を独立させて関係 “書籍作品” を作成
④ 多対多関係を表す中間表 “書籍作品著者” を配置し、外部キーとして
• 著者ID 参照 → 著者
• 書籍作品ID 参照 → 書籍作品
• 著者役割コード 参照 → 著者役割
を設定することで完全従属しか残らず、第3正規形が達成されます。
誤りやすいポイント
- 「主キー列を増やせば正規化できる」と誤解し、冗長列を残したままにしてしまう
- “タイトル” が一意だと思い込み「書籍作品ID」を不要と判断する
- 推移的関数従属と部分関数従属の区別をあいまいにする
FAQ
Q: “著者ID” と “著者名” を同じテーブルに残しても実害がないように見えますが?
A: 更新に伴う入力・修正作業が重複し、データ不整合(綴り違いなど)の温床になります。正規化はそのリスクを排除するために行います。
A: 更新に伴う入力・修正作業が重複し、データ不整合(綴り違いなど)の温床になります。正規化はそのリスクを排除するために行います。
Q: “書籍作品著者” の主キーはどう決めるのですか?
A: 書籍作品ID+著者ID が一意ならそれでも構いませんが、本問では役割が複数存在し得るので「書籍作品ID・著者ID・著者役割コード」の複合キーが無難です。
A: 書籍作品ID+著者ID が一意ならそれでも構いませんが、本問では役割が複数存在し得るので「書籍作品ID・著者ID・著者役割コード」の複合キーが無難です。
Q: 第4正規形やBCNFまで進める必要はありますか?
A: 設問が「第3正規形」までの確認を求めているため、本問では第3正規形を満たせば十分です。
A: 設問が「第3正規形」までの確認を求めているため、本問では第3正規形を満たせば十分です。
関連キーワード: 正規化、関数従属性、主キー、外部キー、リレーション
設問2:図12及び表2について、(1)〜(3)に答えよ。
(1)図2中の(a)〜(d)に入れる適切な属性名を答えよ。また、主キー又は外部キーを構成する属性の場合、主キーを表す実線の下線、又は外部キーを表す破線の下線を付けること。
模範解答
a:会員ID
b:上位カテゴリーコード
c:販売価格
d:出品会員会員ID
解説
解答の論理構成
- 出品会員評価
【問題文】「会員は…出品会員を評価…会員ごと出品会員ごとに最新の評価だけを記録」。
⇒ 主キーは(評価する側、評価される側)。表中で後者は既に “出品会員会員ID” が存在。残る (a) は評価者の 会員ID。 - カテゴリ
【問題文】「カテゴリは階層構造…'データベース' の上位カテゴリが ‘情報技術’」。
⇒ 同一テーブル内で親カテゴリを指す外部キーが必要。図2の (b) 部分はその役割なので 上位カテゴリコード。 - 販売書籍
【問題文】新品・中古いずれも「販売価格」を持つ。図2 “販売書籍” は両者の共通項を格納するスーパタイプ。
⇒ 共通属性として最も重要な金額項目 (c) は 販売価格。 - 中古書籍
【問題文】「出品会員が…中古書籍を出品…」ゆえに誰が出品したかを保存する必要がある。
図2 “中古書籍” には商品番号 PK があり、出品者を示す (d) が欠けている。
⇒ 出品会員会員ID(“出品会員” の PK を参照)が最適。
誤りやすいポイント
- カテゴリ階層を別テーブルで実装すると誤解し、(b) を “カテゴリ階層ID” などと書く。
- “販売書籍” に実在庫数や品質ランクを書いてしまい、共通属性という設計意図を見落とす。
- “中古書籍” に出品者を示すカラムが要ることは気付くが、名称を “会員ID” としてしまい出品者と購入者を混同。
- 主キー・外部キーの下線種別を逆に付ける。
FAQ
Q: “カテゴリ” の主キーは「カテゴリコード」だけで良いのですか?
A: はい。【表1】で「カテゴリを一意に識別するコード」と明示されているので単一キーです。自己参照用の 上位カテゴリコード は外部キー扱いとなります。
A: はい。【表1】で「カテゴリを一意に識別するコード」と明示されているので単一キーです。自己参照用の 上位カテゴリコード は外部キー扱いとなります。
Q: “出品会員評価” に評価日時が無くても最新だけ保持できるの?
A: 最新のみを保持する方針なので履歴は残さず、行の上書きで運用します。キーが (評価者、出品者) であれば時系列情報を別属性に持たなくても常に最新状態です。
A: 最新のみを保持する方針なので履歴は残さず、行の上書きで運用します。キーが (評価者、出品者) であれば時系列情報を別属性に持たなくても常に最新状態です。
Q: “販売書籍” と “新品書籍/中古書籍” の分割は必須?
A: スーパタイプ/サブタイプの正規化で共通属性と個別属性を整理する典型設計です。将来、電子書籍等を拡張する際にも柔軟です。
A: スーパタイプ/サブタイプの正規化で共通属性と個別属性を整理する典型設計です。将来、電子書籍等を拡張する際にも柔軟です。
関連キーワード: 自己参照、スーパタイプ、サブタイプ、主キー、外部キー
設問2:図12及び表2について、(1)〜(3)に答えよ。
(2)図1のエンティティタイプ間のリレーションシップを全て記入せよ。 ただし、エンティティタイプ間の対応関係にゼロを含むか否かの表記は不要である。
なお、識別可能なサブタイプが存在する場合、他のエンティティタイプとのリレーションシップは、カーディナリティの違いを含めてスーパタイプ又はサブタイプのいずれか適切な方との間に記述せよ。 また、図に表示されていないエンティティタイプは考慮しなくてよい。
模範解答

解説
解答の論理構成
-
スーパタイプ/サブタイプの抽出
- 【問題文】「出品会員とは、A 社の EC サイト上で中古書籍を販売できる会員である。」
→「会員」をスーパタイプ、「出品会員」をサブタイプと確定。 - 【問題文】「販売書籍は、新品書籍、中古書籍に分類される。」
→「販売書籍」をスーパタイプ、「新品書籍」「中古書籍」をサブタイプと確定。
- 【問題文】「出品会員とは、A 社の EC サイト上で中古書籍を販売できる会員である。」
-
業務ルールからエンティティ間の実体関係を決定
a. 出品会員と中古書籍- 【問題文】「出品会員が、ECサイト上で中古書籍を出品する」
→ 出品会員 1 - N 中古書籍。
b. 形態別書籍と各サブタイプ - 【問題文】「中古書籍は、1冊ごとに…形態別書籍ID を持つ」
- 【問題文】「新品書籍は、形態別書籍ごとに…」
→ 形態別書籍 1 - N 中古書籍、新品書籍。
c. 会員と出品会員評価 - 【問題文】「会員は…出品会員を評価できる。」
→ 会員 1 - N 出品会員評価。
d. 出品会員と出品会員評価 - 同じ文中に「出品会員を評価できる」とあるため
→ 出品会員 1 - N 出品会員評価。
- 【問題文】「出品会員が、ECサイト上で中古書籍を出品する」
-
スーパタイプ側で表現すべきリレーション
ガイドラインに従い、カーディナリティが同じ場合はスーパタイプで接続。- 販売書籍⇔形態別書籍の直接関係は存在しないため、サブタイプ経由で表現。
- 会員⇔中古書籍の関係も直接には発生しない(注文業務経由)。
-
まとめると、下記8本
① 会員―|<出品会員(汎化)
② 販売書籍―|<中古書籍(汎化)
③ 販売書籍―|<新品書籍(汎化)
④ 出品会員 1―N 中古書籍
⑤ 形態別書籍 1―N 中古書籍
⑥ 形態別書籍 1―N 新品書籍
⑦ 会員 1―N 出品会員評価
⑧ 出品会員 1―N 出品会員評価
誤りやすいポイント
- サブタイプどうし(中古書籍―新品書籍)を直接結んでしまう
- 「会員が中古書籍を購入する」ことから会員―中古書籍を作成してしまう
- 出品会員評価を「多対多」と誤って捉え、中間エンティティを設けてしまう
- 販売書籍を形態別書籍のサブタイプと誤認する(実際は別概念)
FAQ
Q: なぜ「会員」と「新品書籍」にはリレーションシップを描かないのですか?
A: 注文~出荷という業務イベントを介して関係が生じるため、恒常的な存在間関係には当たりません。E-R図ではイベント系エンティティを別途置くか、今回は省略します。
A: 注文~出荷という業務イベントを介して関係が生じるため、恒常的な存在間関係には当たりません。E-R図ではイベント系エンティティを別途置くか、今回は省略します。
Q: 出品会員評価は「最新の評価だけを記録する」とあるが、1 対 1 では?
A: 評価は「会員ごと出品会員ごと」に最新1件ですので、組み合わせ単位では多重度1ですが、出品会員全体で見れば多数の会員が評価できます。したがって出品会員 1―N 出品会員評価となります。
A: 評価は「会員ごと出品会員ごと」に最新1件ですので、組み合わせ単位では多重度1ですが、出品会員全体で見れば多数の会員が評価できます。したがって出品会員 1―N 出品会員評価となります。
Q: スーパタイプ/サブタイプの実線・三角形の向きに決まりはありますか?
A: 一般的には三角形をスーパタイプ側に置き、下辺をサブタイプへ伸ばします。向きよりも「属性と識別子をどこで共有するか」が重要です。
A: 一般的には三角形をスーパタイプ側に置き、下辺をサブタイプへ伸ばします。向きよりも「属性と識別子をどこで共有するか」が重要です。
関連キーワード: ERモデル、カーディナリティ、サブタイプ、汎化、正規化
設問2:図12及び表2について、(1)〜(3)に答えよ。
(3)表2中の(ア)、(イ)に入れる適切な更新処理の内容を、列名及び具体的な更新内容を含め、(ア)は30字以内、(イ)は55字以内で述べよ。
模範解答
ア:ステータス列の値を、'引当済'に更新する。
イ:・実在庫数列及び受注残数列の値を、出荷した数量を減算した値にそれぞれ更新する。
・実在庫数列の値を、出荷した数量を減算した値に更新し、受注残数列の値を、出荷した数量を減算した値に更新する。
解説
解答の論理構成
-
中古書籍のステータス遷移
- 【表1】「ステータス…中古書籍の登録時に『入荷待』、入荷時に『入荷済』、受注時に『引当済』、出荷時に『出荷済』」
- よって受注時(ア)は「'入荷済' → '引当済'」の更新が必要。
-
新品書籍の在庫と受注残
- 新品書籍には【表1】「実在庫数」「受注残数」が存在。
- 【表2】出荷業務で「出荷した販売書籍に該当する、“新品書籍” テーブルの行の(イ)」と指示。
- 出荷が完了した数量は物理在庫・受注残の両方から差し引く必要がある。
- したがって(イ)は「実在庫数列及び受注残数列を出荷数分だけ減算」になる。
誤りやすいポイント
- 「受注時に在庫は減らさない」ことを忘れ、(ア)で在庫列を更新してしまう。
- 新品書籍の「受注残数」を出荷時に減算し忘れる。
- ステータスに存在しない値(例:発送準備中)を勝手に考案して記述する。
FAQ
Q: 受注時に新品書籍の実在庫数を減らさないのはなぜですか?
A: 受注時点ではまだ物理的な出荷が確定しておらず、欠品補充やキャンセルが発生する可能性があるため、実在庫は出荷確定時に調整します。その代わり「受注残数」で引当てを管理します。
A: 受注時点ではまだ物理的な出荷が確定しておらず、欠品補充やキャンセルが発生する可能性があるため、実在庫は出荷確定時に調整します。その代わり「受注残数」で引当てを管理します。
Q: 中古書籍は常に数量1なのに受注残数を持たないのですか?
A: はい。【表1】で「中古書籍の数量は常に1」と定義されており、個別在庫管理なので残数列を持つ必要がありません。ステータスで管理します。
A: はい。【表1】で「中古書籍の数量は常に1」と定義されており、個別在庫管理なので残数列を持つ必要がありません。ステータスで管理します。
Q: 『受注制限フラグ』は出荷時の更新対象ですか?
A: いいえ。『受注制限フラグ』は出版社事情などにより受注可否を制御するためのもので、出荷処理では更新しません。
A: いいえ。『受注制限フラグ』は出版社事情などにより受注可否を制御するためのもので、出荷処理では更新しません。
関連キーワード: 在庫管理、ステータス遷移、受注残、引当、トランザクション
設問3:関係 “出荷”、“出荷明細” について、(1)、(2)に答えよ。
(1)図2中の関係 “出荷”、“出荷明細” には、出荷業務の業務内容を実現できない不具合が二つある。不具合によって実現できない二つの業務内容を、それぞれ35字以内で述べよ。
模範解答
①:同一会員の複数回の注文を一つにまとめて出荷すること
②:同一会員の新品書籍の複数冊の注文を複数回に分割して出荷すること
解説
解答の論理構成
- 要求の確認
出荷業務には次の2要求があります。
・“出荷時点で同一会員から複数回の注文があった場合、一つにまとめて出荷する。”(〔業務の概要〕4.(2))
・“出荷時点で出荷対象の新品書籍の在庫が不足していた場合、実在庫数分だけ出荷し、残りは入荷後に出荷する。”(〔業務の概要〕4.(3)) - 現行スキーマの制約
“出荷” の主キーは “出荷番号”、外部キーとして “注文番号” を保持しており
出荷(出荷番号、注文番号、出荷日時)
となっています。これでは「出荷1件=注文1件」となり、複数注文の統合が不可能です。
さらに “出荷明細” は
出荷明細(出荷番号、商品番号)
であり、数量を保持しないため、同じ “商品番号” を複数行にしても何冊出荷したのか、残数はいくつかを表現できません。 - 不具合との対応付け
・複数注文統合不可 ⇒ 要求4.(2)を満たせない。
・数量分割不可 ⇒ 要求4.(3)を満たせない。
したがって模範解答の2項目に至ります。
誤りやすいポイント
- 「注文番号を持たせればどの注文か分かるから統合できる」と早合点する。実際は1対1制約が生じる点を見落としやすいです。
- 出荷明細に数量列がないことを「中古書籍は必ず1冊」の仕様だけで納得し、新品書籍の複数冊注文を失念する。
- “在庫不足で分割出荷” 要求を「出荷テーブルを複数行にすれば良い」と思い込み、出荷明細と注文明細の整合性を検討しない。
FAQ
Q: 出荷テーブルを注文番号なしにすれば統合出荷は可能ですか?
A: 可能ですが、どの注文をどの出荷で処理したか追跡できなくなるため、多対多連関用の橋渡しテーブル(出荷–注文対応表)が必要です。
A: 可能ですが、どの注文をどの出荷で処理したか追跡できなくなるため、多対多連関用の橋渡しテーブル(出荷–注文対応表)が必要です。
Q: 数量列を追加するだけで分割出荷は実現できますか?
A: 分割出荷では「何冊出荷済みか/残り何冊か」を管理するため、数量列に加え、出荷明細と注文明細の対応関係(注文明細番号など)を保持すると実装が容易になります。
A: 分割出荷では「何冊出荷済みか/残り何冊か」を管理するため、数量列に加え、出荷明細と注文明細の対応関係(注文明細番号など)を保持すると実装が容易になります。
関連キーワード: 正規化、多対多関係、外部キー制約、在庫管理、明細テーブル
設問3:関係 “出荷”、“出荷明細” について、(1)、(2)に答えよ。
(2)(1)の二つの不具合を解消した関係 “出荷”、“出荷明細” の関係スキーマを示せ。
なお、関係スキーマは、第 3 正規形の条件を満たし、主キー及び外部キーを明記すること。 また、主キーを構成する属性の属性名は、図2中の属性名を用いること。
模範解答
出荷(出荷番号、出荷日時)
出荷明細(出荷番号、商品番号、注文番号、出荷数)
解説
解答の論理構成
-
業務要件の整理
- 【問題文】「同一会員から複数回の注文があった場合、一つにまとめて出荷する。」
⇒ 1 つの “出荷番号” が 2 個以上の “注文番号” と結び付く。 - 【問題文】「同じ新品書籍が含まれる場合がある。」
⇒ 1 出荷内で同一 “商品番号” が複数注文にまたがる可能性。
- 【問題文】「同一会員から複数回の注文があった場合、一つにまとめて出荷する。」
-
不具合①:多重従属性
- 元の “出荷(出荷番号、注文番号、出荷日時)” は、主キー “出荷番号” に対し “注文番号” が多値従属する。
- 第 3 正規形条件「主キーに対し非キー属性が完全関数従属」を満たさない。
-
不具合②:注文‐商品対応の欠落
- “出荷明細(出荷番号、商品番号)” だけでは、どの “注文番号” 由来か判別できない。
- 「出荷時点で出荷対象の新品書籍の在庫が不足していた場合…残りは入荷後に出荷」とあるため、後続出荷でも同じ “注文番号” を追跡できる構造が必要。
-
正規化とリレーション再設計
(1) “出荷” から “注文番号” を分離
出荷(出荷番号、出荷日時)
・主キー:出荷番号
(2) “出荷明細” に “注文番号” を追加し出荷行単位で管理
出荷明細(出荷番号、商品番号、注文番号、出荷数)
・主キー:出荷番号 + 商品番号 + 注文番号
・外部キー:
‐ 出荷番号 → 出荷
‐ 商品番号 → 販売書籍
‐ 注文番号 → 注文
(3) これにより
・出荷番号 → 出荷日時(完全関数従属)
・〈出荷番号、商品番号、注文番号〉 → 出荷数(完全関数従属)
となり、第 3 正規形を満たす。
誤りやすいポイント
- “出荷明細” の主キーを〈“出荷番号”、“商品番号”〉のままにする
→ 同じ商品を複数注文分に出荷するケースで一意性が失われる。 - “注文番号” を “出荷明細” のみ複合キーに含めず非キー属性にする
→ 部分関数従属が発生し第 3 正規形違反。 - “出荷数” を追加し忘れる
→ 部分出荷(在庫不足時の分割出荷)を表現できず要件漏れ。
FAQ
Q: なぜ “注文番号” を “出荷” から完全に削除するのですか?
A: 1 つの出荷が複数注文をまとめるため、“出荷番号” から “注文番号” への対応は 1:N ではなく N:M になります。N:M を 1 つの表で表すと多値従属が残るため、連結表である “出荷明細” に移動させます。
A: 1 つの出荷が複数注文をまとめるため、“出荷番号” から “注文番号” への対応は 1:N ではなく N:M になります。N:M を 1 つの表で表すと多値従属が残るため、連結表である “出荷明細” に移動させます。
Q: “出荷明細” の主キーを 3 項目にすると検索性能が落ちませんか?
A: 主キーの複雑さと性能は別問題です。検索頻度の高い列にインデックスを追加すれば性能は確保できます。まずは正規化でデータ不整合を防ぐことが優先です。
A: 主キーの複雑さと性能は別問題です。検索頻度の高い列にインデックスを追加すれば性能は確保できます。まずは正規化でデータ不整合を防ぐことが優先です。
Q: “出荷数” と “注文数” はどう区別しますか?
A: “注文数” は注文時点の数量で “注文明細” に保持します。“出荷数” は実際に出荷した数量で、分割出荷が起こり得るため “出荷明細” に保持します。
A: “注文数” は注文時点の数量で “注文明細” に保持します。“出荷数” は実際に出荷した数量で、分割出荷が起こり得るため “出荷明細” に保持します。
関連キーワード: 正規化、多値従属、複合主キー、外部キー、受注明細


