データベーススペシャリスト 2010年 午後1 問02
データベースの設計に関する次の記述を読んで、設問1〜3に答えよ。
B社は、流通系のクレジットカード会社である。 B社では、新たに開発するシステムに合わせて、現行業務の追加・変更を予定している。 開発プロジェクトではシステム部のC君がデータベースの設計を担当することになった。
〔現行業務の概要〕
1.会員登録
(1) 会員
会員には、一意な会員番号を付与する。 会員は会員区分の値の設定によって、本会員と家族会員に区別する。 さらに、本会員は職業区分の値の設定によって、有職(会社勤務又は自営業)、無職(年金受給、不動産収入など)、及び学生に区別する。
一方、家族会員は、本会員の家族にカードを発行する場合に登録する。 家族会員には、利用明細の表示順を表す家族番号を付与する。
表1に、本会員・家族会員登録時の各設定項目を示す。

(2) 契約
本会員とクレジットカード契約を結ぶ。 契約単位に一意な契約番号を付与し、支払銀行・支店・決済口座番号を設定する。
(3) クレジットカードの発行
本会員及び家族会員に対してクレジットカードを発行する。 本会員に発行するカードを本会員カード、家族会員に発行するカードを家族カードと呼ぶ。 クレジットカードごとに一意なカード番号を付与する。
2.クレジットカードの利用
(1) クレジットカードの利用形態
クレジットカードの利用形態には、ショッピング (物品購入のこと、以下、SHという)とキャッシング (現金借入れのこと、以下、CAという)があり、利用区分に区分値を設定して管理する。 支払方法には、SHでは、1回払い、2回払い、ボーナス1回払い、及びリボルビング (以下、リボという) 払いが、CAでは,1回払いとリボ払いがあり、支払区分に区分値を設定して管理する。 表2に、利用区分・支払区分別の支払方法を示す。

(2) クレジット残高とクレジット枠
引き落としが完了していない利用金額をクレジット残高 (以下、CR残高という)という。CR残高は、CR総残高、利用区分別にSH残高とCA残高、さらに支払区分別にSH1回払い残高などで管理する。 ただし、SH2回払いとボーナス1回払いとは合計残高で管理する。 CR残高の上限値として、クレジット枠(以下、CR枠という)を設定する。 CR枠とCR残高は契約単位に管理する。 表3にCR残高ごとのCR枠を示す。

(3) クレジットカード利用時の確認
クレジットカード利用時には、有効年月、暗証番号などのほかに次のことを確認する。
① 利用区分と支払区分が、表2で示した選択可能な組合せであること (選択不可の場合は“区分エラー” とする)
② 今回の利用金額が、CR枠からCR残高を差し引いた範囲内であること (範囲を超えた場合は “CR枠エラー”とする)
3.利用代金明細書の作成
契約単位に、本会員と家族会員を合わせて月ごとに利用代金明細書を作成し、請求する。 利用代金明細書の例を図1に示す。
(1) 今回請求情報
契約者の住所、氏名、支払年月日、今回請求金額合計などを示す。
(2) 利用明細
前月の利用明細と当月の請求対象となる前々月以前の利用明細について、利用区分別に利用明細番号を利用年月日順に付与し、利用明細番号順に示す。
なお、利用区分と利用年月日が等しい複数の利用明細については、会員が別の場合は本会員、家族番号の小さい家族会員の順に、同じ会員の場合はカードごと利用ごとに付番される利用履歴番号の順に利用明細番号を付与する。
(3) ショッピングリボ払い及びキャッシング支払の明細
利用残高(前回支払後残高+今回利用金額)、今回請求金額(元金+(利息、手数料))、支払後残高などを支払区分ごとに示す。
(4) 契約内容
リボ払い元金支払定額、CA手数料などの契約情報を示す。
〔テーブル設計〕
C君は、現行データベースのテーブル構造を図2のように整理した。
〔現行業務に対する追加・変更〕
B社では、現行業務について、次のような追加・変更を計画している。
(1) 会員登録方法の改善
同一人が重複して家族会員として登録されることがある。 例えば、図3に示すように、共稼ぎ夫婦がそれぞれに本会員カードを保有し、互いに相手に対しての家族カードを保有していたり、子供が両親の家族カードを保有していたりする場合がある。

この点は、会員の利用状況分析では問題があるという判断があり、同一人に対しては、一つの会員レコードだけを対応させることにした。これに伴って、本会員かつ家族会員という会員レコードが存在する。 そのため “会員” テーブルを次のように変更する。
・本会員か家族会員かを排他的に識別していた会員区分を削除する。
・当該会員が、本会員であることを表す本会員フラグ及び家族会員であることを表す家族会員フラグを追加する。
新たに開発するシステムでは、既存会員についてデータ移行時に家族会員の統合を行うことにする。また、新規カード発行に伴う会員登録時には既存会員との照合チェックを行い、既存会員であった場合には新たに会員を登録せずにカードの追加発行を行う。
(2) 分割払の追加
分割払について,6回、12回、24回などの多様な支払方法を選べるようにする。 また、請求時の利用明細欄に、今回の請求が何回目の支払になるのかを回数で示すことにする。ただし、現在のSH2回払いについては変更せず,3回以上の分割払について、新たに支払区分を一つだけ追加するものとする。
解答に当たっては、巻頭の表記ルールに従うこと。
なお、テーブル構造の表記は、“関係データベースのテーブル (表)構造の表記ルール”を用いること。 さらに、主キー及び外部キーを明記せよ。
(1)
“請求” テーブル中の(a)に適切な字句を入れて、テーブルを完成させよ。 ただし、図1中の項目のうち、ほかの項目から導出可能な項目は列としてもたないものとする。また、本文中と同じ意味を表す列名は、本文中の用語を用いること。
模範解答
a:SHリボ前回支払後残高、CAリボ前回支払後残高
解説
解答の導き方
設問は「請求」テーブルの (a) に何を追加すべきかを決める問題です。条件は「図1中の項目のうち、ほかの項目から導出可能な項目は列としてもたない」ことです。まず図1の請求書で印字される主要項目を短く整理し、それぞれが図2のどのテーブル/列から得られるかを順に検討します。
- 図1の主要項目と対応表(要点)
- 「契約者の住所、氏名」 → 会員テーブルの氏名・住所から取得可能です。
- 「支払年月日」 → 請求テーブル自身の列です(図2に既にある)。
- 「利用明細」 → 請求利用明細テーブルとカード利用履歴を結合すれば再現できます(図2に両方のテーブルがある)。
- 「今回請求金額合計」 → 利用明細/支払区分ごとの今回請求金額を合計すれば導出できます。
- 「契約内容(リボ払い元金支払定額、CA手数料 等)」 → 契約情報またはシステム定数から取得できます。
- 「ショッピングリボ払い及びキャッシング支払の明細」に印字される各値(前回支払後残高、今回利用金額、利用残高、今回請求金額、元金、利息・手数料、支払後残高等)については、どこまでを格納すべきかを検討します。
- 「前回支払後残高」が導出可能かの検討
- 本文に「利用残高(前回支払後残高+今回利用金額)」とあり、また図2の契約テーブルには "CR総残高、 SH残高、 S1残高、 S2残高、 SU残高、 CA残高、 C1残高、 CJ残高" (図2の契約列) のように支払区分別の残高を持っていることが分かります。さらに「今回利用金額」は請求利用明細+カード利用履歴の支払区分/利用金額から集計できます。したがって一般に次式で復元できます。
ここで「利用残高」は契約テーブルの該当支払区分の残高(図2のS1残高 等)を指します。つまり、技術的には各支払区分の「前回支払後残高」は他の既存列から導出可能です。
- ではなぜ (a) に列を追加するのか/どの列を追加するか
- ただしビジネス上と仕様(本文)の観点で重要なのは「リボ払いは繰越し(リボ残高)を持ち、利息計算や今回請求額の決定に直接使われる」点です(本文に「リボ残高があれば、(支払定額+リボ残高の利息)を支払う。」とある)。リボは月をまたいで残高が継続するため、請求書に印字される「前回支払後残高」は請求作成時点のスナップショットとして厳密に再現可能である必要があります。
- 他の支払区分(例えばSH1回、CA1回、SH2回/ボーナス等)は原則として翌回支払で精算されるか、または契約テーブルの該当残高と当月の利用明細から復元可能であり、問題文の条件「ほかの項目から導出可能なら列として持たない」に従えば請求テーブルに永続列を追加する必要はありません。図1の例でCA1回に「前回支払後残高」が印字されている例は確かにある(未入金がある等の例外)が、その値は契約側の該当残高と当月利用を使って復元できます。
- 具体例で整合性確認(図1の数値を利用)
- 図1のSHリボ行を見れば、前回支払後残高36,585 + 今回利用金額31,500 = 利用残高68,085、今回請求金額10,451 = 元金10,000 + 利息451となっており、利息算出に前回支払後残高が直接使われていることが分かります。リボの利息計算や「元金支払定額(10,000円)」の扱いを正しく再現するには、請求作成時の「前回支払後残高」を請求レコードとして保持する方が確実です。
以上より、設問の条件(導出可能な項目は持たない)と業務仕様(リボは繰越し・利息計算に前回残高が必要)を両立させると、請求テーブルで恒久的に保持すべき「前回支払後残高」はリボに関するものに限られます。したがって (a) には次の列を追加します(表記は問題文と同一):
SHリボ前回支払後残高、CAリボ前回支払後残高
SHリボ前回支払後残高、CAリボ前回支払後残高
(補足)図1にCA1回の前回残高が印字されているのに請求テーブルにC1前回残高を置かない理由は、CA1回の前回残高は契約テーブルのC1残高 と当月のCA1の利用合計から復元可能であり、問題の制約に従えば冗長となるためです。一方でリボは「繰越し(リボ残高)」が継続的に利用計算に影響するため、請求時のスナップショットを請求レコードに保持するのが妥当です。
誤りやすいポイント
- 図1にCA1回の「前回支払後残高」があることに惑わされ、CA1前回残高を必ず (a) に入れてしまう。図1の例は実例であり得るが、復元可能な項目は「列として持たない」方針に従い不要です。
- すべての支払区分の「前回支払後残高」を請求テーブルに追加してしまう(冗長化・正規化違反)。問題文の条件に反します。
- 「利用残高」と「前回支払後残高」を混同すること。利用残高は契約側の現時点の集計残高(図2の該当列)であり、前回支払後残高は前回請求時の支払後残高(スナップショット)を意味します。差分関係を明確に認識してください。
FAQ
Q: 図1にCA1回の前回支払後残高が印字されているのに、なぜ請求テーブルにCA1前回残高を入れないのですか?
A: 図1の数値はあり得るケースですが、CA1回の前回支払後残高は契約テーブルのC1残高 と当月請求対象のCA1利用金額の集計から計算で復元できます。設問は「導出可能な項目は列として持たない」方針なので、復元可能なCA1の前回残高は請求テーブルに恒久列として持たない判断になります。
A: 図1の数値はあり得るケースですが、CA1回の前回支払後残高は契約テーブルのC1残高 と当月請求対象のCA1利用金額の集計から計算で復元できます。設問は「導出可能な項目は列として持たない」方針なので、復元可能なCA1の前回残高は請求テーブルに恒久列として持たない判断になります。
Q: リボの前回残高はなぜ請求テーブルに保存する必要があるのですか?
A: リボは「繰越し(リボ残高)」が継続し、利息や元金支払定額の計算に前回残高を直接使います(本文に「リボ残高があれば、(支払定額+リボ残高の利息)を支払う。」とある)。請求書の金額を正確かつ再現可能にするため、請求作成時のリボ残高スナップショットを請求レコードに保持するのが適切です。
A: リボは「繰越し(リボ残高)」が継続し、利息や元金支払定額の計算に前回残高を直接使います(本文に「リボ残高があれば、(支払定額+リボ残高の利息)を支払う。」とある)。請求書の金額を正確かつ再現可能にするため、請求作成時のリボ残高スナップショットを請求レコードに保持するのが適切です。
Q: 「今回請求金額合計」は請求テーブルに持つべきですか?
A: 設問の条件に従えば不要です。請求書に表示する合計は請求利用明細や支払区分ごとの今回請求金額を合計すれば導出できます。可搬性や再現性の観点で保存する場合もありますが、本問題では導出可能な項目は列として持たないとしています。
A: 設問の条件に従えば不要です。請求書に表示する合計は請求利用明細や支払区分ごとの今回請求金額を合計すれば導出できます。可搬性や再現性の観点で保存する場合もありますが、本問題では導出可能な項目は列として持たないとしています。
関連キーワード: 正規化、スナップショット、集計処理、参照整合性、冗長化管理
(2)
“契約”テーブルの会員番号と、“カード” テーブルの会員番号は同じ列名であるが、取り得る値の意味が異なる。 その違いを60字以内で述べよ。
模範解答
“契約”の会員番号は、本会員番号に限定されるのに対し、“カード”の会員番号は、すべての会員を対象とする。
解説
解答の論理構成
- 図2のテーブルを確認
- “契約(契約番号、会員番号、契約年月日、…)”
- “カード(カード番号、契約番号、会員番号、…)”
- 業務仕様の確認
- 契約について【問題文】「(2) 契約 本会員とクレジットカード契約を結ぶ」
- カード発行について【問題文】「(3) クレジットカードの発行 本会員及び家族会員に対してクレジットカードを発行する」
- 推論
- 契約を結べるのは本会員のみ ⇒ “契約”の会員番号ドメイン=本会員番号。
- カードは家族会員にも発行 ⇒ “カード”の会員番号ドメイン=全会員番号。
- 結論形成
同一列名でも対象集合が異なるため、意味上の制約を答案にまとめる。
誤りやすいポイント
- 「家族カードも同じ契約にぶら下がるから“契約”にも家族会員番号が入る」と勘違いする。
- 列名が同一なので“同じドメイン”と思い込み、ビジネスルールを読み落とす。
- 「契約=家族を含めた世帯契約」と解釈し、契約単位の定義をずらす。
FAQ
Q: なぜ“カード”には契約番号も会員番号も両方必要なのですか?
A: 1枚のカードは「どの契約で発行されたか」を契約番号で、「誰が使うか」を会員番号で管理するためです。
A: 1枚のカードは「どの契約で発行されたか」を契約番号で、「誰が使うか」を会員番号で管理するためです。
Q: 家族会員が単独で契約を結ぶケースはありますか?
A: 業務仕様より契約は「本会員とクレジットカード契約を結ぶ」とあるため、家族会員単独の契約は想定していません。
A: 業務仕様より契約は「本会員とクレジットカード契約を結ぶ」とあるため、家族会員単独の契約は想定していません。
Q: ドメインが違う場合、列名を変えるべきでしょうか?
A: 運用で混乱する恐れがあればリネームも選択肢ですが、本試験では「列名はそのまま、業務ルールで区別する」前提で設計されています。
A: 運用で混乱する恐れがあればリネームも選択肢ですが、本試験では「列名はそのまま、業務ルールで区別する」前提で設計されています。
関連キーワード: 正規化、ドメイン制約、外部キー、主キー、エンティティ
(3)
“請求利用明細” テーブルについて候補キーを二つ挙げよ。
模範解答
①:・契約番号、支払年月日、利用区分、利用明細番号
②:・カード番号、利用履歴番号、支払年月日
解説
解答の論理構成
- テーブル構造の確認
表示されている「請求利用明細」テーブルの列は
「契約番号、支払年月日、利用区分、利用明細番号、カード番号、利用履歴番号」。 - 請求書側のキーを導く
- 【問題文】では「契約単位に、本会員と家族会員を合わせて月ごとに利用代金明細書を作成」するとある。
- さらに「利用区分別に利用明細番号を利用年月日順に付与」するため、1請求書(=「契約番号」「支払年月日」)・1利用区分内で「利用明細番号」が重複しない。
- よって「契約番号、支払年月日、利用区分、利用明細番号」で一意。
- カード利用履歴側のキーを導く
- 図2の「カード利用履歴」テーブルは「カード番号、利用履歴番号」で主キーを構成すると読み取れる。
- 1つの利用履歴は“どの月の請求書に載るか”が「支払年月日」で決まる。
- したがって「カード番号、利用履歴番号、支払年月日」でも一意。
- “候補キー”なので複数列挙
- いずれも重複が起こらずNULL不可の組合せであり、主キー候補となる。
誤りやすいポイント
- 「利用明細番号」単独、または「契約番号+利用明細番号」で唯一と思い込む
→ 利用区分が異なると同じ番号が再利用される。 - 「カード番号+利用履歴番号」で十分と判断
→ 同一利用履歴が複数回請求されるケース(月跨ぎ)を想定できていない。 - 候補キーは1つしか答えてはいけないと誤解する。
FAQ
Q: 主キーと候補キーの違いは何ですか?
A: 候補キーの中から物理的に表の主キーとして“採用”されたものが主キーです。候補キーは一意性を満たす列集合が複数あっても良く、今回2通り示しています。
A: 候補キーの中から物理的に表の主キーとして“採用”されたものが主キーです。候補キーは一意性を満たす列集合が複数あっても良く、今回2通り示しています。
Q: 「支払年月日」をキーに含める理由は?
A: 同じ契約でも月が違えば別請求書になります。請求書単位で利用明細を区分するため「支払年月日」を含めないと重複する可能性があります。
A: 同じ契約でも月が違えば別請求書になります。請求書単位で利用明細を区分するため「支払年月日」を含めないと重複する可能性があります。
Q: 「利用区分」はキーに必須ですか?
A: 明細番号が「利用区分」ごとにリセットされる仕様(【問題文】「利用区分別に利用明細番号を…付与」)なので、キーに含めないと1と2のように重複します。
A: 明細番号が「利用区分」ごとにリセットされる仕様(【問題文】「利用区分別に利用明細番号を…付与」)なので、キーに含めないと1と2のように重複します。
関連キーワード: 候補キー、主キー設計、一意性制約、外部キー、第3正規形
設問2:現行業務におけるテーブル内の項目の制約について(1)、(2)に答えよ。
問題文を見る(1)
“会員” テーブルの項目は、NULL不可となることが静的に決まらないので、列ごとに NOT NULL制約を定義できない。 そこで、C君はNULL不可であることを動的に管理する“項目チェック” テーブルを図4のように定義した。図4中の(b)に適切な字句を入れて、テーブルを完成させよ。 ただし、“会員” テーブルの列又は職業区分の区分値が追加された場合にも、“項目チェック” テーブルの行の追加だけで対応できるものとする。 また、本文中と同じ意味を表す列名は、本文中の用語を用いること。


模範解答
b:一連番号、会員列名称、会員区分、職業区分
解説
解答の論理構成
-
キー項目の洗い出し
- 問題文より引用:
「“会員” テーブルの項目は、NULL不可となることが静的に決まらない」
「列又は職業区分の区分値が追加された場合にも…行の追加だけで対応」 - したがって「列名」も「区分値」もデータとして保持しなければ拡張要求を満たせません。
- 問題文より引用:
-
判定に必要な三つの自然キー
- 会員列名称 … どの列を対象にした制約か
- 会員区分 … 本会員/家族会員など列挙型の区分値
- 職業区分 … 有職/無職/学生など列挙型の区分値
-
行の一意性と更新の容易さ
- 複合主キーでも構いませんが、(会員区分、職業区分) がNULLになるケース(「すべての区分に共通の制約」を表現)を扱いやすくするためSurrogate Keyを採用します。
- これを問題文の語句で表すと「一連番号」が適切です。
-
列順序の決定
- 実務的には主キーである「一連番号」を先頭に置き、その後に識別条件である三列を配置するのが自然です。
-
よって (b) は
- 一連番号、会員列名称、会員区分、職業区分
誤りやすいポイント
- 「会員列名称」を列にせず、制約を列ベースの固定列(氏名_NOT_NULLなど)で持たせてしまうと、列追加のたびにテーブル定義を変更しなければならなくなります。
- (会員区分、職業区分) を主キーにすると、両方がNULLの行を複数持てず「全区分共通の制約」を複数行で登録できないため拡張性が落ちます。
- 区分値を整数コードで扱う場合でも、問題文は「本文中と同じ意味を表す列名は、本文中の用語を用いること」と指示しているので、列名にコードや略称を使わないよう注意が必要です。
FAQ
Q: 一連番号は必ずしも必要ですか?
A: 問題文の将来拡張要件を考えると、複合主キーよりSurrogate Keyの方が汎用的で扱いやすいため「一連番号」を置くのが妥当です。
A: 問題文の将来拡張要件を考えると、複合主キーよりSurrogate Keyの方が汎用的で扱いやすいため「一連番号」を置くのが妥当です。
Q: 会員区分や職業区分がNULLの場合はどう解釈しますか?
A: 該当列をNULLにすると「すべての区分に共通の制約」を意味します。行を追加するだけで共通/個別双方に対応できます。
A: 該当列をNULLにすると「すべての区分に共通の制約」を意味します。行を追加するだけで共通/個別双方に対応できます。
Q: 「会員列名称」には実際にどのような値が入りますか?
A: “会員” テーブルの列名そのもの(例:「氏名」「住所」「勤務先名」など)を格納します。これにより列の追加時も行追加だけで管理可能になります。
A: “会員” テーブルの列名そのもの(例:「氏名」「住所」「勤務先名」など)を格納します。これにより列の追加時も行追加だけで管理可能になります。
関連キーワード: 正規化、Surrogate Key, NULL制約、動的スキーマ管理、メタデータテーブル
設問2:現行業務におけるテーブル内の項目の制約について(1)、(2)に答えよ。
問題文を見る(2)
クレジットカード利用時に、利用形態別に利用金額をチェックし、正常終了とエラーを判定する次の決定表中の、(c)〜(e)に適切な字句を入れて表を完成させよ。


模範解答
c:CA枠-CA残高
d:S2枠-S2残高
e:C1枠-C1残高
解説
解答の論理構成
- “利用区分”と“支払区分”の整理
- 【問題文】「利用区分には、ショッピング(SH)、キャッシング(CA)があり」
- 支払区分は表2により “1回払い〔1〕”、“2回払い〔2〕”、“ボーナス1回払い〔3〕”、“リボ払い〔4〕”。
- CR枠とCR残高の対応表を確認
- 【問題文】「表3」に次の行がある。
• 「S2残高」/「S2枠」:利用区分1、支払区分2及び3
• 「CA残高」/「CA枠」:利用区分2、支払区分 すべて
• 「C1残高」/「C1枠」:利用区分2、支払区分1
- 【問題文】「表3」に次の行がある。
- 決定表 a・b の読替
- a は “利用区分1” が並ぶ=ショッピング系。
- 既に「SH枠-SH残高」「S1枠-S1残高」が登場しているため、残る支払区分2・3用の行が (d)。
- よって (d)=「S2枠-S2残高」。
- (c) の導出
- b で “利用区分2” が多く、ここで (c) 行が判定に使われている。
- 利用区分2全般で使われるのは「CA枠-CA残高」。
- よって (c)=「CA枠-CA残高」。
- (e) の導出
- CAのうち “支払区分1” だけを対象にした個別行が必要。
- 表3の「CA1回払い残高」/「C1枠」が該当するため (e)=「C1枠-C1残高」。
誤りやすいポイント
- 「SH2回払い」と「ボーナス1回払い」を別々に管理すると早合点し、(d) を2行に分けてしまう。
- 「CA枠-CA残高」があれば個別枠は不要と思い込み、(e) の存在を見落とす。
- 表3の略称と決定表の記号を対応付けずに暗記しようとして混乱する。
FAQ
Q: 「S2残高」はどの支払区分をまとめた残高ですか?
A: 【問題文】「表3」で「利用区分1」「支払区分2及び3」の行が「SH2回払いとボーナス1回払いの合計残高」と明示されています。したがって2回払いとボーナス1回払いを合算した残高がS2残高です。
A: 【問題文】「表3」で「利用区分1」「支払区分2及び3」の行が「SH2回払いとボーナス1回払いの合計残高」と明示されています。したがって2回払いとボーナス1回払いを合算した残高がS2残高です。
Q: キャッシング1回払いとリボ払いは同じCA枠でチェックしても良いのでは?
A: CA全体の上限は「CA枠-CA残高」で確認しますが、支払区分1については「CA1回払い残高」をさらに「C1枠」で個別管理する仕様になっています(表3「C1枠」行)。よって両方のチェックが必要です。
A: CA全体の上限は「CA枠-CA残高」で確認しますが、支払区分1については「CA1回払い残高」をさらに「C1枠」で個別管理する仕様になっています(表3「C1枠」行)。よって両方のチェックが必要です。
Q: 決定表に同じY/Nパターンが並ぶ行が複数あるのはなぜですか?
A: 利用区分・支払区分の組合せごとに“どの枠で上限確認を行うか”が異なるためです。同じ TRUE/FALSE でも参照する列(枠)が違えば行を分けて記述する必要があります。
A: 利用区分・支払区分の組合せごとに“どの枠で上限確認を行うか”が異なるためです。同じ TRUE/FALSE でも参照する列(枠)が違えば行を分けて記述する必要があります。
関連キーワード: 上限制約、決定表、サブクレジット枠、支払区分、データ正規性
設問3:〔現行業務に対する追加・変更〕 について、(1)、(2)に答えよ。 ただし、設問2で問う内容は考慮しないものとする。
問題文を見る(1)
図2のテーブル構造に、会員登録方法の改善策を施したとしても、ほかにもまだ不具合がある。
(a)不具合のあるテーブル名を一つ挙げ、不具合の内容を35字以内で述べよ。
(b)新たにテーブルを作成せずに不具合を解決するために、変更すべきテーブル名、列名を挙げよ。 また、当該列の変更操作を、削除又は追加のいずれかで答えよ。 ただし、会員区分の削除、本会員フラグ及び家族会員フラグの追加については除くものとする。
模範解答
(a) テーブル名:会員テーブル
不具合の内容:複数の家族会員がいたとき、家族番号と続柄を全員分登録できない。
(b) :


解説
解答の論理構成
- 事実の整理
- 家族属性はカード発行時点で決まる(家族カード単位の情報)。
- 問題文は「同一人に対しては、一つの会員レコードだけを対応させる」と明示。
- 不具合の指摘
- 会員行に「家族番号」「続柄」を置くと、本会員フラグ=1かつ家族会員フラグ=1の場合に複数値を保持できず、家族が2人以上いると上書きや欠落が生じる。
- これは第1正規形違反(列に複数値)。
- 解決方針
- 家族カードごとに家族番号と続柄を管理すれば、1人が複数の家族カードを持ってもカード行で1:1に保持できる。
- 追加テーブルは禁止されているので、「カード」テーブルへ列移動。
- 列操作
- 「会員」テーブル:家族番号、続柄 → 削除
- 「カード」テーブル:家族番号、続柄 → 追加
これで会員⇔カードが1対多となり整合性が保たれる。
誤りやすいポイント
- 「家族番号」を契約単位と誤解し「契約」テーブルへ移そうとする
- 新テーブル(例:家族会員テーブル)を作ってしまい“作成せずに”の条件違反
- 会員区分削除の指示と列移動を混同し、不要列まで削る
- 続柄はリファレンス情報だから削除だけで良いと判断し追加を忘れる
FAQ
Q: 家族番号と続柄を会員テーブルに残しつつ多値を扱う方法はありますか?
A: ありますが推奨されません。たとえば区切り文字付きリストや集合型を使う方法がありますが、第1正規形違反となり検索・更新が複雑化します。
A: ありますが推奨されません。たとえば区切り文字付きリストや集合型を使う方法がありますが、第1正規形違反となり検索・更新が複雑化します。
Q: 「カード」テーブルに移動すると家族番号の一意性はどう担保しますか?
A: 主キーは既存の「カード番号」です。家族番号は同一契約内で連番にするなど追加の一意性制約を設けるか、複合キー(契約番号、家族番号)を候補キーとして定義するとよいでしょう。
A: 主キーは既存の「カード番号」です。家族番号は同一契約内で連番にするなど追加の一意性制約を設けるか、複合キー(契約番号、家族番号)を候補キーとして定義するとよいでしょう。
Q: 本会員と家族会員の判定はどこで行うのですか?
A: 会員行に追加した本会員フラグ・家族会員フラグで判定し、カード行の家族番号がNULLなら本会員カード、値があれば家族カードと判断する運用が一般的です。
A: 会員行に追加した本会員フラグ・家族会員フラグで判定し、カード行の家族番号がNULLなら本会員カード、値があれば家族カードと判断する運用が一般的です。
関連キーワード: 第1正規形、多値属性、外部キー、主キー、列移動
設問3:〔現行業務に対する追加・変更〕 について、(1)、(2)に答えよ。 ただし、設問2で問う内容は考慮しないものとする。
問題文を見る(2)
分割払の追加のために、“カード利用履歴” テーブルと “請求利用明細” テーブルに追加すべき列名をそれぞれ答えよ。
模範解答
カード利用履歴:分割回数
請求利用明細:今回回数、今回請求金額
解説
解答の論理構成
- 仕様把握
- 【問題文】「3回以上の分割払について、新たに支払区分を一つだけ追加」とあり、支払回数が可変になる。
- 同じく「今回の請求が何回目の支払になるのかを回数で示す」と指示。
- “カード利用履歴” への影響
- 取引登録時点で総回数を確定する必要がある。
- 既設列では2回までしか保持できず拡張性がない。
⇒ 総回数を表す単独列「分割回数」を追加。
- “請求利用明細” への影響
- 毎請求サイクルごとに「今回が○回目」「今回請求金額」を出力する必要。
- テーブル設計上、請求情報の粒度と一致するのは “請求利用明細”。
⇒ 「今回回数」「今回請求金額」を追加。
- 主キー・外部キーに変更はなく、列の追加のみで要件を満たせる。
誤りやすいポイント
- 「第1回支払金額」「第2回支払金額」で対応できると誤解し、列追加を省いてしまう。3回以上では不足します。
- 「今回回数」を “カード利用履歴” に入れるミス。これは請求タイミングごとに変化する値なので別テーブルが妥当です。
- 列名の表記ブレ(「分割支払回数」など)で減点。列名はシンプルに「分割回数」「今回回数」「今回請求金額」とします。
FAQ
Q: 「分割回数」を “請求利用明細” にも入れるべきでは?
A: 総回数は取引固定情報なので “カード利用履歴” に一元管理すれば冗長性がなくなります。“請求利用明細” では参照で足ります。
A: 総回数は取引固定情報なので “カード利用履歴” に一元管理すれば冗長性がなくなります。“請求利用明細” では参照で足ります。
Q: 「今回請求金額」は “請求” テーブルに入れないの?
A: “請求” は契約月次の集計単位で、明細粒度の金額は “請求利用明細” が適所です。個々の利用明細行を表示する要件に合致します。
A: “請求” は契約月次の集計単位で、明細粒度の金額は “請求利用明細” が適所です。個々の利用明細行を表示する要件に合致します。
Q: 既存の「支払区分」で6回・12回などを区別する必要は?
A: 仕様に「新たに支払区分を一つだけ追加」とあるため、区分値は一本化し、実際の回数は「分割回数」で判別します。
A: 仕様に「新たに支払区分を一つだけ追加」とあるため、区分値は一本化し、実際の回数は「分割回数」で判別します。
関連キーワード: 分割払い、支払区分、テーブル設計、カラム追加、データ冗長性





