応用情報技術者 2009年 秋期 午後 問06
旅行業務用データベースの設計に関する次の記述を読んで、設問1~3に答えよ。
旅行会社であるZ社では、四半期ごとにパッケージツアー(以下、ツアーという)の計画を作成し、発売開始後、申込みを受け付ける。Z社には、本社のほかに、地域ごとに支店があり、ツアーの申込みは、インターネットと支店店頭の両方で行える。また、ツアーの申込みに関するデータは、本社のデータベースで一括して管理する。
〔ツアー〕
・ツアーにはツアーコードが付されている。ツアーの内容が同じであれば、出発日が異なってもツアーコードは同じであるが、日数が異なればツアーコードは異なる。
・ツアーは、ツアーコードが同じでも、出発日によって価格が異なることがある。
〔ツアーに関する業務〕
・ツアーの申込みを受け付けたときには、申込番号、申込者の顧客番号、申込日、申し込んだツアーのツアーコード、そのツアーの出発日、参加人数を登録する。新規の顧客の場合には顧客番号を新たに設定し、顧客の氏名、住所、郵便番号、電話番号、電子メールアドレスを登録する。
・ツアーを申し込んだ顧客には、店頭での申込みかインターネットからの申込みかにかかわらず、それ以降、支店から四半期ごとにツアーなどに関する情報をダイレクトメールで送付する。顧客を担当する支店は、顧客の郵便番号によって決めている。発送は、その時点で担当となっている支店が行う。なお、支店間の業務量の均等化のために、担当範囲を随時見直すことにしている。
〔データベースの設計〕
・E-R図を作成してテーブル設計を行った結果、ツアーテーブル、申込みテーブル、顧客テーブル、支店テーブルの四つのテーブルから成るデータベースを作成することにした。
・E-R図を図1に、設計したテーブルを表1に示す。なお、表1において、下線の引かれた列名は、主キーである。


〔データベースの運用〕
・ツアーテーブルには、四半期ごとにその期のツアー商品を追加する。当該四半期の間にツアーテーブルの内容が変更されることはない。
・ツアーの申込みを受け付けるごとに、申込みテーブルに行を1件追加する。申込番号は、ツアーの申込み1件ごとに設定する。
〔正規化に関する検討〕
ツアーテーブルの非キー属性の中には、候補キーに完全関数従属していない属性が存在するので、ツアーテーブルは第二正規形ではない。すなわち、非キー属性であるaとbが、候補キーの一部であるcだけに関数従属している。
顧客テーブルの非キー属性の中には、ほかの非キー属性を介して候補キーに関数従属(推移関数従属)している属性があるので、顧客テーブルは第三正規形ではない。具体的には、非キー属性であるdは、やはり非キー属性であるeに関数従属している。ただし、Z社では、入力間違いなどの可能性を考慮し、顧客テーブルの郵便番号は住所に関数従属しないものと考えている。
設問1:
本文中のa〜eに入れる適切な字句を解答群の中から選び、記号で答えよ(aとbは順不同)。
解答群
ア:価格
イ:顧客番号
ウ:氏名
エ:住所
オ:出発日
カ:担当支店コード
キ:ツアーコード
ク:ツアー名称
ケ:電子メールアドレス
コ:電話番号
サ:日数
シ:郵便番号
模範解答
a:サ
b:ク
c:キ
d:カ
e:シ
解説
解答の論理構成
- ツアーテーブルの候補キー
【問題文】では「ツアーテーブル」の主キーが「ツアーコード、出発日」であると明示されており、これは複合キーです。 - 第二正規形の条件確認
第二正規形にするには「非キー属性が候補キーの全項目に完全関数従属」していなければなりません。 - 非キー属性ごとの依存関係を整理
- 「ツアーコード」が同じでも「出発日」によって「価格」が変わる → 「価格」は「ツアーコード」「出発日」の両方に依存。
- 「ツアーコード」が同じなら「日数」「ツアー名称」は変わらない → 両者は「ツアーコード」のみに依存。
したがって「日数」「ツアー名称」が部分関数従属に該当し、【問題文】の
「非キー属性であるaとbが、候補キーの一部であるcだけに関数従属している」
に当てはまります。
・a=「日数」(サ)
・b=「ツアー名称」(ク)
・c=「ツアーコード」(キ)
(※a と b は順不同なので逆でも正解)
- 顧客テーブルの第三正規形違反を確認
【問題文】では「顧客を担当する支店は、顧客の郵便番号によって決めている」とあります。これは
「郵便番号」→「担当支店コード」
の関数従属を意味します。さらに「顧客番号」→「郵便番号」であるため、 「顧客番号」→「郵便番号」→「担当支店コード」
となり、「担当支店コード」は候補キーである「顧客番号」に対して推移的に関数従属します。
よって
・d=「担当支店コード」(カ)
・e=「郵便番号」(シ)
誤りやすいポイント
- 「価格」は出発日により変動するので部分関数従属ではないことを見落としやすい。
- 「郵便番号→住所」と思い込み、「住所」がeだと誤答するケースが多い。問題文には「郵便番号は住所に関数従属しないものと考えている」と明記されている。
- E-R図の矢印に気を取られ、論点が正規化であることを忘れると判断がブレやすい。
FAQ
Q: 「日数」と「ツアー名称」のどちらが a でも良いのですか?
A: はい。【問題文】に「a と b は順不同」と指示があるため、どちらを a・b にしても正解です。
A: はい。【問題文】に「a と b は順不同」と指示があるため、どちらを a・b にしても正解です。
Q: 「担当支店コード」が主キーでないのに推移的従属になるのはなぜ?
A: 第三正規形の条件は「主キー以外の非キー属性が他の非キー属性に依存しない」ことです。「担当支店コード」は非キー属性なので、「郵便番号」に依存している時点で推移的従属となります。
A: 第三正規形の条件は「主キー以外の非キー属性が他の非キー属性に依存しない」ことです。「担当支店コード」は非キー属性なので、「郵便番号」に依存している時点で推移的従属となります。
Q: 「住所」は郵便番号から決まるのでは?
A: 問題文に「入力間違いなどの可能性を考慮し、顧客テーブルの郵便番号は住所に関数従属しないものと考えている」と書かれているため、今回は従属関係がないものとして扱います。
A: 問題文に「入力間違いなどの可能性を考慮し、顧客テーブルの郵便番号は住所に関数従属しないものと考えている」と書かれているため、今回は従属関係がないものとして扱います。
関連キーワード: 正規化、第二正規形、推移的関数従属、候補キー、部分関数従属
設問2:正規化に関する検討について、(1)〜(3)に答えよ。
(1)テーブルが第二正規形ではない場合、一般的には様々な問題が発生する可能性がある。しかし、ツアーテーブルの場合にはそのような問題は発生しないと考えられる。その理由を、本文の記述に照らし合わせて35字以内で述べよ。
模範解答
ツアーテーブルに追加された行がその後変更されることはないから
解説
解答の論理構成
- 問題文は、ツアーテーブルが第二正規形ではない理由として「非キー属性であるaとbが、候補キーの一部であるcだけに関数従属している」と述べています。これは複合キーの一部に対する部分関数従属であり、通常は更新・挿入・削除異常の原因になります。
- ところが「データベースの運用」において、ツアーテーブルについて「ツアーテーブルには、四半期ごとにその期のツアー商品を追加する。当該四半期の間にツアーテーブルの内容が変更されることはない。」と明言されています。
- 行が“追加のみ”で“更新・削除をしない”運用であれば、第二正規形に満たないことによる更新異常は発生しません。
- したがって、「ツアーテーブルに追加された行がその後変更されることはないから」という解答になります。
誤りやすいポイント
- 「常に正規化しなければならない」と思い込み、運用ポリシーを無視してしまう。
- 「変更されない」という文を読み落とし、通常の更新異常リスクをそのまま当てはめてしまう。
- 部分関数従属=必ず問題、と短絡的に判断し、実際のビジネスルール(追加のみ)と結び付けられない。
FAQ
Q: 第二正規形にしなくても本当に問題は起きませんか?
A: 運用が「追加のみ」で「更新・削除を行わない」限り、部分関数従属による更新異常は生じません。運用変更時には再検討が必要です。
A: 運用が「追加のみ」で「更新・削除を行わない」限り、部分関数従属による更新異常は生じません。運用変更時には再検討が必要です。
Q: 追加専用テーブルでも正規化するべきでは?
A: 保守性・将来拡張を考えると正規化は望ましいですが、本問では四半期ごとに固定化される性質を優先し、性能や設計工数を抑える判断と読めます。
A: 保守性・将来拡張を考えると正規化は望ましいですが、本問では四半期ごとに固定化される性質を優先し、性能や設計工数を抑える判断と読めます。
Q: 部分関数従属と推移的関数従属の違いは何ですか?
A: 部分関数従属は「複合キーの一部にのみ依存」、推移的関数従属は「非キーが別の非キーを介してキーに依存」する状態です。
A: 部分関数従属は「複合キーの一部にのみ依存」、推移的関数従属は「非キーが別の非キーを介してキーに依存」する状態です。
関連キーワード: 第二正規形、部分関数従属、更新異常、データ冗長性、運用ポリシー
設問2:正規化に関する検討について、(1)〜(3)に答えよ。
(2)顧客テーブルが第三正規形でないために発生する問題を、本文の記述に照らし合わせて60字以内で述べよ。
模範解答
支店の担当範囲が変更されると、顧客テーブルの該当するすべての行の担当支店コードを修正しなければならない。
解説
解答の論理構成
- 顧客テーブルの主キーは「顧客番号」であり、非キー属性に「郵便番号」と「担当支店コード」が存在します。
- 本文には、顧客を担当する支店は「顧客の郵便番号によって決めている」とあります。したがって「担当支店コード」は「郵便番号」に関数従属します。
- さらに「郵便番号」は主キー「顧客番号」に関数従属するので、「担当支店コード」は主キーに対して推移的に関数従属していることになります。これは第三正規形の条件(非キー属性は候補キーに対して推移的依存を持たない)に違反します。
- 本文には「担当範囲を随時見直す」とあるため、郵便番号と支店の対応が変わることがあります。このとき、「顧客テーブル」の複数行に同じ「郵便番号」が記録されていると、紐づく「担当支店コード」もすべて更新する必要が生じます。
- 以上より、第三正規形を満たしていないと更新負荷が集中する更新異常が発生し、「支店の担当範囲が変更されると、顧客テーブルの該当するすべての行の担当支店コードを修正しなければならない。」という模範解答に至ります。
誤りやすいポイント
- 「郵便番号→担当支店コード」の依存を見落とし、主キー依存だと勘違いする。
- 「担当範囲を随時見直す」記述を読み飛ばし、更新異常のリスクを具体的に想像できない。
- “第二正規形”と“第三正規形”の条件を混同し、部分関数従属と推移的関数従属を区別できない。
FAQ
Q: 「郵便番号」も非キー属性ですが、なぜ問題になるのですか?
A: 非キー属性同士の依存(郵便番号→担当支店コード)が存在し、推移的関数従属が発生しているためです。
A: 非キー属性同士の依存(郵便番号→担当支店コード)が存在し、推移的関数従属が発生しているためです。
Q: どう修正すれば第三正規形になりますか?
A: 「郵便番号」「担当支店コード」を分離し、郵便番号をキーとした別テーブルを設けることで推移的依存を排除できます。
A: 「郵便番号」「担当支店コード」を分離し、郵便番号をキーとした別テーブルを設けることで推移的依存を排除できます。
Q: 更新異常が放置されるとどんな実害がありますか?
A: 支店範囲変更時に一部行の更新漏れが発生し、誤った支店からダイレクトメールが送付されるなどサービス品質が低下します。
A: 支店範囲変更時に一部行の更新漏れが発生し、誤った支店からダイレクトメールが送付されるなどサービス品質が低下します。
関連キーワード: 更新異常、推移的関数従属、第三正規形、正規化、関数従属
設問2:正規化に関する検討について、(1)〜(3)に答えよ。
(3)顧客テーブルを第三正規形になるように分解せよ。新規に追加するテーブルには適切なテーブル名を付け、表1に倣って列名を記述し、主キーを示す下線を引くこと。
模範解答
テーブル名:列名
顧客:顧客番号、氏名、住所、郵便番号、電話番号、電子メールアドレス
担当支店:郵便番号、担当支店コード
解説
解答の論理構成
-
依存関係の確認
問題文には、 ・「顧客を担当する支店は、顧客の郵便番号によって決めている。」
・「顧客テーブルの非キー属性の中には、ほかの非キー属性を介して候補キーに関数従属(推移関数従属)している属性がある」
とあり、さらに
・「非キー属性であるdは、やはり非キー属性であるeに関数従属している。」
と示されています。
ここでd=「担当支店コード」、e=「郵便番号」であることは、顧客テーブル中で唯一“支店”を示す列が「担当支店コード」であり、その決定要因が「郵便番号」だと述べられていることから分かります。 -
推移的関数従属の特定
顧客テーブルの主キーは「顧客番号」。したがって
「顧客番号」 → 「郵便番号」 → 「担当支店コード」
という推移的関数従属が存在し、第三正規形(3NF)を満たしません。 -
分解方針
第三正規形では「非キー属性は候補キーに対して推移的に従属してはならない」ため、 「郵便番号」→「担当支店コード」の依存関係を独立テーブルに切り出します。 -
分解後のテーブル
【顧客】
顧客番号、氏名、住所、郵便番号、電話番号、電子メールアドレス【担当支店】
郵便番号、担当支店コードこれにより、顧客テーブルは
・主キー「顧客番号」→残るすべての非キー属性
のみとなり、推移的依存が取り除かれて第三正規形が達成されます。
誤りやすいポイント
- 「住所が同じなら郵便番号が同じ」と思い込み、郵便番号→住所と逆方向の依存を設定してしまう。問題文には「入力間違いなどの可能性を考慮し、顧客テーブルの郵便番号は住所に関数従属しない」と明記されています。
- 「担当支店コード」を主キーにしたくなるが、問題文は「顧客を担当する支店は、顧客の郵便番号によって決めている」と述べており、郵便番号が決定属性です。
- 顧客テーブルから「郵便番号」まで削除してしまうと、顧客の住所情報と DM 送付業務に支障が出るため、郵便番号は顧客テーブルに残す必要があります。
FAQ
Q: 将来、郵便番号と担当支店コードの対応が変わった場合はどう扱いますか?
A: 「担当支店」テーブルの該当行を更新するだけで済み、顧客テーブルの行を個別に更新する必要がありません。これが正規化の更新容易性です。
A: 「担当支店」テーブルの該当行を更新するだけで済み、顧客テーブルの行を個別に更新する必要がありません。これが正規化の更新容易性です。
Q: 「担当支店」テーブルに支店名を入れなくてもよいのですか?
A: 支店名は「支店」テーブルに保持されており、「担当支店コード」で参照できます。同じ列を二重に持たせないことでデータの整合性を保ちます。
A: 支店名は「支店」テーブルに保持されており、「担当支店コード」で参照できます。同じ列を二重に持たせないことでデータの整合性を保ちます。
関連キーワード: 正規化、第三正規形、推移的関数従属、主キー、データベース設計
設問3:
現在の設計では、ツアーに参加した人全員の情報をデータベースに保持しているわけではないので、参加者全員にダイレクトメールを送ることはできない。そこで、それぞれのツアーの参加者全員の情報をデータベースに格納することを検討する。そのために、図1のE-R図にエンティティを一つ追加する。また、それに従って、申込者に加えて全参加者の情報を顧客テーブルに格納するとともに、新たなテーブルを追加して、申込番号ごとに、そのツアーに参加するすべての顧客の顧客番号を保持するようにする。
これを実現するために、図1に対して、適切な名称を付したエンティティを追加し、リレーションシップを記入せよ。
模範解答
(図を参照)


解説
解答の論理構成
-
現状把握
【問題文】では「現在の設計では、ツアーに参加した人全員の情報をデータベースに保持しているわけではない」と明示されています。既存の E-R 図は
・「顧客」―「申込み」―「ツアー」―「支店」
という4エンティティ構成で、申込者1名しか顧客テーブルへ紐付きません。 -
要件の抽出
新たに「申込番号ごとに、そのツアーに参加するすべての顧客の顧客番号を保持するようにする」と指示されています。
したがって「申込み」と「顧客」の間で
・1件の「申込み」に対して複数の「顧客」
・1人の「顧客」は複数の「申込み」に参加可能
という多対多関係が発生します。 -
多対多解消の原則
リレーショナル設計では多対多は直接表現できないため、中間エンティティ(交差テーブル)を設けて2本の1対多に分解します。 -
追加エンティティの命名
参加事実を表すため最も直感的で業務に即した名称が「参加」です。問題の【模範解答】画像でも矩形ラベルは「参加」となっています。 -
関係・カーディナリティ設定
・「申込み」(1)―(多)「参加」
主キー「申込番号」を「参加」の外部キーに。
・「顧客」(1)―(多)「参加」
主キー「顧客番号」を「参加」の外部キーに。 -
テーブル設計の示唆
「参加」テーブルの主キーは「申込番号」+「顧客番号」。これで1申込みに同一顧客を重複登録できないという業務制約も担保されます。 -
期待される効果
これにより「参加者全員にダイレクトメールを送る」要件が、顧客テーブルと参加テーブルで実現できます。
誤りやすいポイント
- 申込者と参加者の混同
「参加人数」をそのまま人数カウント用属性と誤解し、個々の参加者行を作成しないケースが頻出します。 - 多対多のままモデリング
「顧客」と「申込み」を直接多対多で結び、交差エンティティを作らない誤設計に注意。 - 主キー設計の漏れ
「参加」テーブルで「申込番号」だけ、あるいは「顧客番号」だけを主キーにすると一意性が崩れます。 - 外部キー重複登録
参加テーブルに存在しない「申込番号」や「顧客番号」を登録して参照整合性エラーとなるケース。
FAQ
Q: 追加した「参加」テーブルに氏名や住所を持たせてもよいですか?
A: 持たせると冗長になり更新時に不整合が起きます。個人情報は「顧客」テーブル1か所で管理し、参加テーブルはキーのみ保持するのが正規化の原則です。
A: 持たせると冗長になり更新時に不整合が起きます。個人情報は「顧客」テーブル1か所で管理し、参加テーブルはキーのみ保持するのが正規化の原則です。
Q: 「参加人数」列は残すべきでしょうか?
A: 参加テーブルができた後も残せますが、参加テーブルの行数を集計すれば人数が得られるため冗長です。ETL 速度など実務上の理由が無い限り削除する方が整合的です。
A: 参加テーブルができた後も残せますが、参加テーブルの行数を集計すれば人数が得られるため冗長です。ETL 速度など実務上の理由が無い限り削除する方が整合的です。
Q: 家族で同一ツアーを複数回申し込む場合、同じ「顧客番号」を再利用して良い?
A: はい。「顧客番号」は個人単位で不変です。同じ顧客が別の「申込番号」に紐づくたびに参加テーブルへ新行を追加し、履歴を蓄積します。
A: はい。「顧客番号」は個人単位で不変です。同じ顧客が別の「申込番号」に紐づくたびに参加テーブルへ新行を追加し、履歴を蓄積します。
関連キーワード: 多対多解消、交差エンティティ、外部キー制約、主キー設計、第三正規形


