データベーススペシャリスト 2013年 午後1 問02
受注管理システムのデータベース設計に関する次の記述を読んで、設問1〜3に答えよ。
A社は、個人宅を訪問し、主にキッチン、浴室、洗面所、トイレなどの清掃をサービスとして提供する業者である。 A社では、受注管理システムを新たに構築することになり、B君がデータベース設計を任された。
〔業務概要〕
1.組織の特性
(1) 地域ごとに店舗があり、本店及び各店舗はそれぞれ店舗番号で一意に識別される。
(2) 本店は顧客からの引合いを受け付け、各店舗は引合いのあった顧客の見積りを行い、注文が確定した後、サービスを実施する。
2.会員の特性
顧客は、最初の注文時に会員登録される。 会員は、会員番号で一意に識別される。
3.サービスの特性
(1) サービスは、サービスコードで一意に識別される。
(2) サービスには、個別サービス、セットサービス及びオプションサービスの3種類があり、サービス区分でどの種類のサービスかが識別される。
① 個別サービスとは、キッチン清掃、レンジフード清掃、浴室清掃など、1 か所の清掃を指す。 個別サービスのサービス内容、標準価格、標準作業時間数は決まっている。 個別サービスの例を表1に示す。
② セットサービスとは、個別サービスを複数組み合わせたもので、個別サービスそれぞれの標準価格の合計よりも割安な価格で提供する。 セットサービスに対して、選択可能な個別サービス群、選択可能数、標準価格は決まっている。一つの個別サービスは、複数の異なるセットサービスに組み込まれることがある。セットサービスの例を表2に示す。
③ オプションサービスとは、会員の依頼によって個別サービスに追加する清掃で、単独では提供しない。 オプションサービスのサービス内容、適用可能な個別サービス、標準価格、標準作業時間数は決まっている。一つのオプションサービスを適用できる個別サービスは、一つだけである。 一つの個別サービスに対して、複数のオプションサービスを追加できる。 セットサービスで選択した個別サービスに対しても、オプションサービスを追加できる。 オプションサービスの例を表3に示す。



4.注文の特性
(1) 注文は、注文番号で一意に識別される。
(2) 注文にはスポット注文と継続注文があり、注文区分で識別される。
① スポット注文とは,1回だけ清掃を行うケースの注文である。
② 継続注文とは、同じ清掃を複数回にわたって行うケースの注文である。
・会員は、期間、回数及び曜日を選択する。
・会員は、期間と回数について、24週間に6回,48週間に6回,48 週間に 12回など、あらかじめ決められた組合せの中から選択する。
・期間、回数、曜日の組合せは、継続パターンコードで識別される。また、それによって継続割引率は異なる。
(3) 一つの注文で、複数のサービスを指定できる。また、個別サービスとセットサービスを一緒に指定することもできる。
5.引合い、見積り、注文の確定の流れ
(1) 本店で受け付けた引合いは、地域ごとの店舗に割り当てられる。割り当てられた店舗は、会員宅を訪問して見積りを行う。
(2) 見積りによって、サービスごとの実施項目、適用価格が確定する。継続注文の場合、この確定内容は,2 回目以降も継続する前提である。適用価格は、標準価格と異なる場合がある。
(3) 見積りにおいて、予定年月日、予定開始時刻、予定終了時刻を決定する。継続注文の場合、予定開始時刻と予定終了時刻は2回目以降もこの決定が適用されるが、予定年月日は初回だけに適用される。
(4) 見積り結果は、セットサービスで選択した個別サービス、及び個別サービスに追加したオプションサービスの対応関係が分かるように、サービス名の前に記号を付け、関係するサービスを並べて表示する。 また、同一の清掃を複数箇所に対して行う場合、それぞれを識別できるようにするために、実施場所に、所在を表示する。 見積り結果の例を図1に示す。
(5) 会員が見積り結果を確認し、同意すれば注文が確定する。

6.実施の流れ
(1) 会員宅を訪問して注文内容に従って清掃を行う単位を、“実施”と呼ぶ。 スポット注文では1回の注文で1回の実施が発生し、継続注文では1回の注文で複数回の実施が発生する。
(2) 1回の実施に対して、一意となる実施番号が付与される。 1回の実施には一つ又は複数のサービスが含まれ、サービスごとに実施明細番号が付与される。
(3) 注文確定によって、スポット注文と継続注文の初回の実施予定を決定し、登録する。 その際、個別サービス、オプションサービスごとに、予定作業時間数を割り当てる。
(4) 継続注文の2回目以降は、実施時に次回の予定年月日を決め、その時点で次回の実施予定を登録する。
(5) 1回の実施で予定していた、全ての清掃が終了した時点で、実施年月日、実施開始時刻、実施終了時刻を登録する。 また、個別サービス、オプションサービスごとに実施作業時間数を登録する。
(6) サービスごとの実施作業時間数は、サービスの作業改善、標準作業時間数の見直しのために、過去の実績を分析する場合に照会する。
〔データベースの設計〕
B君は、現在の業務概要と次の方針に基づいて、テーブル構造を図2のように設計することにした。
(1) セットサービスで選択された個別サービスも、単品で選択された個別サービスも、“注文明細” テーブルには同様の形式で格納する。
(2) 注文の確定時に“注文” テーブル及び “注文明細” テーブルに行を作成する。実施予定登録時に “実施” テーブル及び “実施明細” テーブルに行を作成する。
(3) “実施” テーブルの行から対応する “注文” テーブルの行、“実施明細” テーブルの行から対応する “注文明細” テーブルの行を特定するために、外部キーを設定する。


〔継続注文の変更〕
検討中のテーブル構造では、継続注文について、初回の実施後、継続する 2 回目以降にオプションサービスの追加及び取消しを行いたくても対応できない。この点について、会員からの要望を満たせていないことが判明した。 そこで、B君は、2 回目以降の実施に対して、オプションサービスの追加及び取消しを行えるように、次の対応を考えた。
(1) 次回の実施予定を決定するときに、変更の要望を確認し、変更があれば必要な見積りを実施して、適用価格と変更の要望に伴う予定開始時刻及び予定終了時刻の変更を決定する。
(2) 当初の注文確定時点の情報を含め、変更履歴を注文変更年月日ごとに保存する。
解答に当たっては、巻頭の表記ルールに従うこと。
なお、テーブル構造の表記は、“関係データベースのテーブル (表) 構造の表記ルール” を用いること。 さらに、主キー及び外部キーを明記せよ。
また、新たに追加するテーブル名及び列名は、本文中で与えられた語句を用いて適切な名称とすること。
設問1:図2の“サービス” テーブルと “継続パターン” テーブルについて、(1)〜(3)に答えよ。
(1)
“サービス” テーブルには、セットサービス、個別サービス及びオプションサービスの3種類のサービスが格納される。 そこで、“サービス” テーブルを,3 種類のサービスに共通の列をもつ“サービス共通” テーブルと、各サービスに固有の列をもつテーブルに分割することにした。 列が冗長にならないように、各テーブルの構造を記述せよ。
模範解答
サービス共通(サービスコード、サービス区分、サービス名、標準価格)
個別サービス(サービスコード、サービス内容、標準作業時間数)
セットサービス(サービスコード、個別サービス選択可能数)
オプションサービス(サービスコード、サービス内容、標準作業時間数、個別サービスコード)
解説
解答の論理構成
-
列の性質を分類
- 【問題文】「サービス区分でどの種類のサービスかが識別される」
- 共通:サービスコード、サービス区分、サービス名、標準価格
- 個別専用:サービス内容、標準作業時間数
- セット専用:個別サービス選択可能数
- オプション専用:サービス内容、標準作業時間数、個別サービスコード
-
非キー属性は主キーに完全従属させる
- 個別サービスの「標準作業時間数」は“個別サービス”.サービスコードにのみ依存。
- オプションサービスの「個別サービスコード」は、オプションサービスにだけ意味を持つ外部キー。
-
サブタイプ実装方式を決定
- サービスごとに行を分ける「1対1派生テーブル方式」を採用し、4表でサブタイプを表現。
- これにより上位表(サービス共通)と下位表が で接続され、検索もシンプル。
-
主キー・外部キー設定
- 四つのテーブルすべてでサービスコードを主キー。
- “オプションサービス”.個別サービスコード は“個別サービス”.サービスコードへの外部キー。
誤りやすいポイント
- 「サービス内容」を“サービス共通”に残すとセットサービスにも必須になり NULL が発生。
- 「標準作業時間数」を“サービス共通”に置くとセットサービスでは無意味。
- オプションサービスが参照する個別サービスを「外部キーにし忘れる」ため、整合性が取れなくなる。
- 4表に分割した後、既存のテーブル(例:注文明細)が参照すべき列を更新し忘れる。
FAQ
Q: なぜ「サービス区分」を“サービス共通”に残すのですか?
A: 上位表だけでレコードの種類を判別できるようにするためです。下位表を結合しなくても分類が分かり、応答性能と管理性が向上します。
A: 上位表だけでレコードの種類を判別できるようにするためです。下位表を結合しなくても分類が分かり、応答性能と管理性が向上します。
Q: “セット組合せ”テーブルは変更不要ですか?
A: はい。主キー「セットサービスコード、個別サービスコード」はそのまま“セットサービス”のサービスコードを参照するだけでよく、構造変更は不要です。
A: はい。主キー「セットサービスコード、個別サービスコード」はそのまま“セットサービス”のサービスコードを参照するだけでよく、構造変更は不要です。
Q: サブタイプ方式を使うと JOIN が増えて遅くなりませんか?
A: サービス表はマスタとして小規模です。I/O コストは僅少で、正規化による整合性確保のメリットが上回ります。
A: サービス表はマスタとして小規模です。I/O コストは僅少で、正規化による整合性確保のメリットが上回ります。
関連キーワード: 正規化、サブタイプ、主キー、外部キー
設問1:図2の“サービス” テーブルと “継続パターン” テーブルについて、(1)〜(3)に答えよ。
(2)
“継続パターン” テーブルの候補キーを全て答えよ。なお、複数の列から構成される候補キーは{ }でくくること。
模範解答
継続パターンコード、{期間、回数、曜日}
解説
解答の論理構成
- テーブル属性の整理
“継続パターン” テーブルは【図2】に示す
「継続パターンコード」「期間」「回数」「曜日」「継続割引率」
の5列で構成されています。 - 一意性を示す業務記述
【問題文】4.(2)② に
「期間、回数、曜日の組合せは、継続パターンコードで識別される。」
とあるため、 ・継続パターンコード
は当然一意(候補キー①)。
・逆に期間
+回数
+曜日
も1行を一意に決定(候補キー②)。 - 他列はキーにならない
継続割引率
は割引率を示す属性であり、同じ割引率が複数行に出現し得るため一意性を担保しません。 - よって候補キーは2つ
①継続パターンコード
②{期間、回数、曜日}
誤りやすいポイント
継続割引率
を含めて{期間、回数、曜日、継続割引率}としてしまう。- 「識別される」という文言を見落とし、複合キーを導けない。
- 主キーと候補キーの違いを混同し、「主キーは1つだから候補キーも1つ」と誤解する。
FAQ
Q: 候補キーと主キーの違いは何ですか?
A: 候補キーは行を一意に識別できる列(または列集合)の候補全てを指し、その中から実際にテーブル設計で選択・採用したものが主キーです。
A: 候補キーは行を一意に識別できる列(または列集合)の候補全てを指し、その中から実際にテーブル設計で選択・採用したものが主キーです。
Q:
A: いいえ、一意性は要件にありません。同じ割引率でも期間や回数が異なれば別レコードになります。
継続割引率が同じ行が複数あってはいけないのですか?
A: いいえ、一意性は要件にありません。同じ割引率でも期間や回数が異なれば別レコードになります。
Q: 複合キーを書く順序は評価に影響しますか?
A: 成分が同じなら順序は評価に影響しませんが、答案では問題文に従って「{期間、回数、曜日}」と記述すると誤解が生じにくいです。
A: 成分が同じなら順序は評価に影響しませんが、答案では問題文に従って「{期間、回数、曜日}」と記述すると誤解が生じにくいです。
関連キーワード: 候補キー、複合キー、関数従属、正規化
設問1:図2の“サービス” テーブルと “継続パターン” テーブルについて、(1)〜(3)に答えよ。
(3)
“継続パターン” テーブルは、第1正規形、第2正規形、第 3 正規形のうち、どこまで正規化されているか。 また、部分関数従属性、推移的関数従属性の有無を、“あり” 又は “なし”で答えよ。“あり” の場合は、その関数従属性の具体例を、次の表記法に従って示せ。


模範解答
正規形:第3正規形
部分関数従属性の有無:なし
推移的関数従属性の有無:なし
解説
解答の論理構成
- 主キーの確認
【問題文】“継続パターン” テーブルの属性は
― “継続パターンコード”
― “期間”
― “回数”
― “曜日”
― “継続割引率”
と列挙され、「“継続パターンコード”に下線:主キー」と明示されています。 - 関数従属性の列挙
主キーが一意にレコードを決定するので
継続パターンコード → 期間、回数、曜日、継続割引率
が唯一の関数従属性です。 - 第1正規形の判定
すべての列は原子値で繰返し項目も無いので第1正規形を満たします。 - 第2正規形の判定
主キーが単一列である以上、部分関数従属性は理論的に生じません。従って第2正規形も充足します。 - 第3正規形の判定
非キー属性(期間、回数、曜日、継続割引率)間の依存は示されておらず、推移的関数従属性は発生しません。よって第3正規形に到達しています。 - まとめ
・正規形:第3正規形
・部分関数従属性:なし
・推移的関数従属性:なし
誤りやすいポイント
- 「複合キーかどうか」を確認せずに自動的に部分関数従属性があると決めつける。
- 「期間」「回数」「曜日」の組合せが主キー候補だと勘違いし、余計な依存関係を作る。
- 非キー属性同士を “常識的に関連がありそう” という感覚で結び付け、推移的関数従属性と誤認する。
FAQ
Q: 「第2正規形=複合キーでないと関係ない」と覚えていて良いですか?
A: 厳密には「主キーが単一列なら、その時点で部分関数従属性が存在し得ないので第2正規形を自動的に満たす」と理解すると安全です。
A: 厳密には「主キーが単一列なら、その時点で部分関数従属性が存在し得ないので第2正規形を自動的に満たす」と理解すると安全です。
Q: 「曜日」や「期間」などを別テーブルに分割する必要はありますか?
A: 正規化の観点では必要ありません。現在の依存関係では “継続パターンコード” が全てを一意に決定し、第3正規形に達しているためです。
A: 正規化の観点では必要ありません。現在の依存関係では “継続パターンコード” が全てを一意に決定し、第3正規形に達しているためです。
Q: もし将来「継続割引率」が “期間×回数” で決まる仕様に変わったら?
A: その時点で「期間、回数 → 継続割引率」という推移的関数従属性が発生するため、第3正規形を維持するにはテーブル分割が必要になります。
A: その時点で「期間、回数 → 継続割引率」という推移的関数従属性が発生するため、第3正規形を維持するにはテーブル分割が必要になります。
関連キーワード: 正規化、主キー、部分関数従属性、推移的関数従属性、第3正規形
設問2:図2の“注文明細” テーブルについて、(1)、(2)に答えよ。
(1)
注文明細のサブタイプ構造を図3に示す。この3種類のサブタイプは、一つの注文の中で対応関係をもち得る。 その対応関係を示すリレーションシップを図 3 に記入せよ。 その場合、対応関係にゼロを含むか否かを区別して表現する場合の表記ルールを用いること。


模範解答

解説
解答の論理構成
- セットサービス ➔ 個別サービス
- 図 1 に「水まわり3点セット…◆浴室清掃…」の列挙があるため、セットに属する個別サービスが存在する。
- 一方、「6|トイレ清掃」や「7|エアコン清掃」のようにセットに属さない個別サービスも同一注文内に登場する。
- よって個別サービス側から見て “0 又は 1” のセットに従属、セット側から見ると設定された「選択可能数」が 1 以上なので “1 以上”。
- 個別サービス ➔ オプションサービス
- 【問題文】「一つの個別サービスに対して、複数のオプションサービスを追加できる。」
- 同時に「オプションサービスは…単独では提供しない。」のでオプション側は必ず 1 つの個別サービスに従属。
- 個別サービスにはオプションを付けなくても良い(図 1 で ◆浴室清掃にオプション無しなど)ため、個別サービス側は “0 以上”。
- 表記
- 指定の“ゼロを含むか否かを区別して表現する表記ルール”に合わせ、
・「○|●|→」で “0 又は 1 対 1 以上”
・「●|○|→」で “1 対 0 以上”
を用いると模範解答の図式になります。
- 指定の“ゼロを含むか否かを区別して表現する表記ルール”に合わせ、
・「○|●|→」で “0 又は 1 対 1 以上”
誤りやすいポイント
- 「個別サービスは必ずセットかオプションのどちらかに属する」と早合点し、個別サービス単品注文を忘れる。
- オプション側の必須従属(単独禁止)を見落として “0 又は 1” と書いてしまう。
- “選択可能数”をそのまま最大多重度に誤適用し、セット側を “1” 固定で描かない。
- IE 記法の記号位置を逆に書き,0/1 を左右混同する。
FAQ
Q: セットサービスに個別サービスが 0 件になることはありますか?
A: ありません。注文確定時点で「選択可能数」が最低 1 以上決められているため、セット側には必ず 1 件以上の個別サービスがひも付きます。
A: ありません。注文確定時点で「選択可能数」が最低 1 以上決められているため、セット側には必ず 1 件以上の個別サービスがひも付きます。
Q: オプションサービスを複数付けたときの多重度はどう考えますか?
A: 「一つの個別サービスに対して、複数のオプションサービスを追加できる。」という記述から個別サービス側は “0 以上”、オプション側は “必ず 1 つの個別サービス” です。
A: 「一つの個別サービスに対して、複数のオプションサービスを追加できる。」という記述から個別サービス側は “0 以上”、オプション側は “必ず 1 つの個別サービス” です。
Q: 継続注文で 2 回目以降にオプションを追加した場合、多重度は変わりますか?
A: 変わりません。変更履歴は別テーブルで管理し、個々の実施明細単位で見ればオプションは常に “0 以上” の関係を保ちます。
A: 変わりません。変更履歴は別テーブルで管理し、個々の実施明細単位で見ればオプションは常に “0 以上” の関係を保ちます。
関連キーワード: 多重度、サブタイプ、IE記法、外部キー、リレーションシップ
設問2:図2の“注文明細” テーブルについて、(1)、(2)に答えよ。
(2)
(1)で答えたリレーションシップを成り立たせるために、現在の“注文明細”テーブルに列を二つ追加することにした。 それらの列に設定する値の意味を、具体的にそれぞれ40字以内で述べよ。
模範解答
①・選択された個別サービスの元となったセットサービスの注文明細番号
②・追加されたオプションサービスの元となった個別サービスの注文明細番号
解説
解答の論理構成
-
サービス間の階層関係
- 問題文「3. サービスの特性 (2) ② セットサービスとは、個別サービスを複数組み合わせたもの」とあるように、セットサービスは必ず個別サービスを内包します。
- 同じく「3. サービスの特性 (2) ③ オプションサービスとは、…個別サービスに追加する清掃で、単独では提供しない」とあるため、オプションサービスは常に個別サービスに従属します。
-
図3が要求するリレーションシップ
- 「図3 注文明細のサブタイプ構造」では “セットサービス 注文明細” → “個別サービス 注文明細” → “オプションサービス 注文明細” の上下関係を明示しています。
- この上下関係を物理実装するには、子側行から親側行を指すキーが必要です。
-
追加すべき列の内容
- セットサービス配下の個別サービスであれば「どのセットサービスに属するか」を示す値が必要。
⇒ ①「選択された個別サービスの元となったセットサービスの注文明細番号」。 - 個別サービス配下のオプションサービスであれば「どの個別サービスに付随するか」を示す値が必要。
⇒ ②「追加されたオプションサービスの元となった個別サービスの注文明細番号」。
- セットサービス配下の個別サービスであれば「どのセットサービスに属するか」を示す値が必要。
-
自己参照で完結
- “注文明細” テーブル自身に親を示す列を追加すれば、セット・個別・オプションの3層を同一テーブル内で表現できます。
- 既存の主キー “注文番号+注文明細番号” は変更不要で、外部キーとして同テーブルを参照するだけで済むため実装が簡潔です。
誤りやすいポイント
- 「セットサービス自体が個別サービスを示す列を持つ」と勘違いし、重複列を作ってしまう。
- オプションサービスは「セットサービスにも直接ぶら下がる」と誤解するが、問題文では必ず個別サービス経由です。
- 親子関係を表す列に “サービスコード” を入れようとしてしまい、“注文明細番号” でなければ階層が一意に特定できない点を見落とす。
FAQ
Q: 注文明細に自己参照の外部キーを追加すると循環参照になりませんか?
A: 参照は親→子の一方向なので循環しません。列は NULL 許容にしてルート(セットサービス行)の親キーを空欄にすれば処理可能です。
A: 参照は親→子の一方向なので循環しません。列は NULL 許容にしてルート(セットサービス行)の親キーを空欄にすれば処理可能です。
Q: 複数階層でも同一列で賄えるのですか?
A: はい。セットサービス行は NULL、個別サービス行はセットサービスの番号、オプションサービス行は個別サービスの番号を格納するだけで3層を表現できます。
A: はい。セットサービス行は NULL、個別サービス行はセットサービスの番号、オプションサービス行は個別サービスの番号を格納するだけで3層を表現できます。
Q: 追加列の名前に決まりはありますか?
A: 本文の語句を使う指示に従い「親注文明細番号」など “注文明細番号” を含む名前にすると可読性と要件を両立できます。
A: 本文の語句を使う指示に従い「親注文明細番号」など “注文明細番号” を含む名前にすると可読性と要件を両立できます。
関連キーワード: 自己参照外部キー、階層構造、サブタイプ、リレーションシップ、データ正規化
設問3:注文と実施の管理について(1)、(2)に答えよ。
(1)
“実施明細” テーブルの行は “注文明細”テーブルの行に基づいて作成される。その際に、“実施明細” テーブルに反映する必要がない “注文明細” テーブルの行がある。 その行を15字以内で述べよ。 また、反映する必要がない理由を20字以内で述べよ。
模範解答
行:セットサービス注文明細の行
理由:セットサービスは実施対象ではないから
解説
解答の論理構成
- テーブル間の生成タイミング
- 注文確定 → “注文明細” に行作成
- 実施予定登録 → “実施明細” に行作成
- 実施対象のサービス種別
- “サービスには、個別サービス、セットサービス及びオプションサービスの3種類”
- “セットサービスとは、個別サービスを複数組み合わせたもの”
- 現場で行う作業
- “1回の実施には一つ又は複数のサービスが含まれ” とあるが、 個別に作業時間を割り当てる仕様は “個別サービス、オプションサービスごとに、予定作業時間数を割り当てる。”
- 逆に “セットサービス” に対して作業時間は割り当てない。
- よって “実施明細” を作る際、実際に清掃しない “セットサービス注文明細の行” は反映不要となり、理由は “セットサービスは実施対象ではないから” となる。
誤りやすいポイント
- “個別サービスを3件まとめたので作業時間を記録するだろう” と考え、セットサービスも実施対象に含めてしまう。
- 「選択した個別サービス」と「親セットサービス」の両方を二重登録して冗長なデータを生む。
- “オプションサービス” を忘れ、実施明細に含めないミス。
FAQ
Q: セットサービスが実施明細に無いと価格履歴が欠落しませんか?
A: “適用価格” は “注文明細” に残るため請求・分析は可能です。実施明細は作業実績専用と割り切ります。
A: “適用価格” は “注文明細” に残るため請求・分析は可能です。実施明細は作業実績専用と割り切ります。
Q: サービス区分を見れば判別できますか?
A: はい。“サービス区分” 列で “セット” を除外すれば実施明細に積み上げる対象を機械的に抽出できます。
A: はい。“サービス区分” 列で “セット” を除外すれば実施明細に積み上げる対象を機械的に抽出できます。
Q: 今後セットサービス単位で作業時間を管理したい場合は?
A: セットサービス自体に標準作業時間数を持たせ、新たに実施明細へ紐付ける列を追加すれば対応可能です。
A: セットサービス自体に標準作業時間数を持たせ、新たに実施明細へ紐付ける列を追加すれば対応可能です。
関連キーワード: サブタイプ構造、外部キー制約、正規化、業務要件分析
設問3:注文と実施の管理について(1)、(2)に答えよ。
(2)
〔継続注文の変更〕 に対応するために、次の方針でテーブルの構造を見直すことにした。
・新たなテーブルは追加せず、図2のテーブル構造を変更する。
・テーブル構造の変更は、変更対象のテーブルに対して、同じ役割の列を一つだけ追加する。
この方針で見直した場合の追加する列について、役割を表す適切な列名を答えよ。 また、変更すべきテーブル名を全て答え、それらのテーブルごとに、追加する列が主キーを構成する場合は主キー欄に “○”、外部キーを構成する場合は外部キー欄に“○” を記入して、次の表を完成させよ。
なお、表の欄は全て埋まるとは限らない。


模範解答
列名:注文変更年月日
テーブル:


解説
解答の論理構成
- 追加すべき列名
要件より引用:
「変更履歴を注文変更年月日ごとに保存する」
⇒ 列名はそのまま「注文変更年月日」。 - どのテーブルに入れるか
変更が影響する範囲は「注文」~「実施明細」までの4表。
【問題文】「当初の注文確定時点の情報を含め、変更履歴を…保存する」
① 注文:変更を起点とするため必須。
② 注文明細:サービス単位の見積りが変わるので必須。
③ 実施:次回以降の予定を登録し直すので必須。
④ 実施明細:作業時間・価格も版管理が要るので必須。 - 主キーへの組み込み可否
- 注文:元々主キーは「注文番号」。版を区別するには複合化が必要 ⇒ 主キー欄に○
- 注文明細:主キーは「注文番号+注文明細番号」。注文番号が変わらないので同様に複合化 ⇒ 主キー欄に○、さらに親表を参照するため外部キー欄も○
- 実施:主キー「実施番号」は変更しない。列は実施版の参照用途のみ ⇒ 外部キー欄に○
- 実施明細:主キーは「実施番号+実施明細番号」。版管理は親子参照で足りる ⇒ 外部キー欄に○
- 以上を表形式に整理
誤りやすいポイント
- 「実施」「実施明細」には変更列が不要と早合点し、後続実施の履歴が管理できなくなる。
- 列名を「変更年月日」などと省略し、原文「注文変更年月日」と不一致にしてしまう。
- 主キーを追加列で置き換えてしまい、既存システムとの参照整合性を壊す。
FAQ
Q: 注文変更年月日は NULL を許可してもよいですか?
A: 初回確定分にも値が必要なので NULL 非許可にします。初回は確定日=変更年月日と考えます。
A: 初回確定分にも値が必要なので NULL 非許可にします。初回は確定日=変更年月日と考えます。
Q: 実施番号が一意なら実施表に列を入れなくても良いのでは?
A: 実施表は「注文」表を外部キーで参照します。親表の複合主キーに列が増えると、子表の外部キーにも同じ列が必要です。
A: 実施表は「注文」表を外部キーで参照します。親表の複合主キーに列が増えると、子表の外部キーにも同じ列が必要です。
Q: 変更履歴は最大何回でも対応できますか?
A: 日付列を版識別子に使うため回数制限は実質ありません。年月日が重複しなければ任意回数の変更を保存できます。
A: 日付列を版識別子に使うため回数制限は実質ありません。年月日が重複しなければ任意回数の変更を保存できます。
関連キーワード: 履歴管理、複合主キー、外部キー参照、バージョン管理、第三正規形


