DBデータベーススペシャリスト試験 午後Ⅰ

令和6年度秋期 データベーススペシャリスト 午後Ⅰ 問3

事例を読んで設問の答えを考えてから、解説のポイントとIPA公式の解答例・採点講評で確認しましょう。

問題

問3 情報システム会社のプロジェクト稼働管理システムのデータベース物理設計・SQL設計・性能に関する次の記述を読んで,設問に答えよ。 情報システム会社のE社は,自社のプロジェクト稼働管理システム(以下,PJシステムという)を,RDBMSを用いて更改することになり,Fさんが実装を任された。 〔RDBMSの主な仕様〕 1.DMLのアクセス経路は,RDBMSによって索引探索又は表探索が選択される。 2.索引は,クラスタ性という性質によって,高クラスタな索引と低クラスタな索引に分けられる。 ・高クラスタな索引は,キー値の順番と,キーが指す行の物理的な並び順が一致しているか,完全に一致していなくても,隣接するキーが指す行が同じページに格納されている割合が高い。 ・低クラスタな索引は,キー値の順番と,キーが指す行の物理的な並び順が一致している割合が低く,行へのアクセスがランダムになる。 〔業務の概要〕 1.組織,従業員,役職,ランク,時間単価 (1)E社には,複数の組織がある。組織は階層構造であり,最上位の組織以外はいずれか一つの上位組織に属する。 (2)従業員は,従業員コードで識別し,いずれか一つの組織に属する。 (3)役職には,SE,シニアSE,マネージャなどがある。役職は役職コードで識別する。従業員はいずれか一つの役職をもつ。 (4)ランクは,労務費の時間単価を区別するもので,ランクコードで識別する。役職はいずれか一つのランクに対応する。 (5)時間単価は,ランク別組織別年月日別に決めている。組織の変更,従業員の異動などによって,月初に時間単価を見直すことがある。 2.プロジェクト,稼働計画,稼働実績 (1)プロジェクト(以下,PJという)は,従業員の稼働状況を管理する単位である。従業員は複数のPJに参加することがあり,PJに参加していない従業員も一部いる。 (2)PJに必要な人員を要員という。 (3)PJ開始前に稼働計画を立案するとき,要員ごと参加年月ごとに計画時間を見積もる。参加する従業員が確定したとき,稼働計画の要員に対して従業員を割り当てる。PJ開始後,必要に応じて計画を修正する。 (4)PJに参加している各従業員は,稼働実績として月内の日別PJ別の稼働時間を入力する。従業員は同じ日に複数PJの稼働時間を入力できる。 〔PJシステムのテーブル〕 1.テーブル構造,列の意味・制約,統計情報・索引定義 主なテーブルのテーブル構造を図1に,主な列の意味・制約を表1に示す。また,“従業員”テーブルの主な統計情報・索引定義を表2に,“稼働実績”テーブルの主な統計情報・索引定義を表3に示す。 図1 主なテーブルのテーブル構造 表1 主な列の意味・制約 2.“従業員”テーブルの行更新における更新履歴処理 “従業員”テーブルの組織コード,役職コードを更新するとき,当該従業員の更新前の行を更新の履歴として“従業員履歴”テーブルに挿入する。 3.“組織”テーブルの行削除処理 E社では,組織の改廃がある。PJ管理に不要になった組織コードを削除する場合,次のような手順で行う。 ①廃止済みの組織であり,かつ,PJが終了済みなどPJ管理に不要と判断できる組織コードを,SELECT文を用いて調べる。 ②①で調べた組織コードの行を,“組織”テーブルからDELETE文を用いて削除する。 〔テーブルの定義と実装〕 1.テーブルの定義 (1)Fさんは,図1中の各テーブルを定義するCREATE TABLE文を設計した。ここで,各CREATE TABLE文には外部キー制約を実装することとした。そのうち,“組織”テーブルを定義するCREATE TABLE文を,図2に示す。 図2 “組織”テーブルを定義するCREATE TABLE文 (2)Fさんは,他の表が未定義の状態で“組織”テーブルを定義する図2のCREATE TABLE文を実行したところ失敗した。そこで,Fさんは,図2のCREATE TABLE文を見直し,次の①~③の順番で定義を実行したところ,全ての実行が成功した。 ①“組織”テーブルを定義する図2中から,【a】を外部キーとする指定を削除したCREATE TABLE文を実行する。 ②“従業員”,“役職”,“時間単価”,“ランク”の各テーブルを定義するCREATE TABLE文を“【b】”,“【c】”,“役職”,“【d】”の順番で実行する。 ③“組織”テーブルに対する【e】文を用いて,【a】を外部キーとする指定の定義を追加する。 2.テーブルへの行登録 次に,Fさんは,“組織”テーブルにINSERT文を用いて行を挿入した。次いで,“従業員”,“役職”,“時間単価”,“ランク”の各テーブルに対してもINSERT文を用いて行を挿入した。その後,UPDATE文で適宜列値を更新した。 〔稼働計画の立案・稼働実績の確認〕 Fさんは,稼働計画の立案及び稼働実績の確認を支援するためのSQL文を設計した。設計したSQL文の例を,表4に示す。 表4 稼働計画の立案及び稼働実績の確認を支援するSQL文の例 〔問合せの性能改善〕 Fさんは,“稼働実績”テーブルへの問合せに利用される表4中のSQL2について,性能の改善を依頼された。Fさんが調べたところ,稼働実績を一括入力する従業員が多く,1か月単位で見たとき,行の登録順が従業員,稼働年月日,PJコード順であり,従業員当たり1か月分の行が高々2ページに格納されることが分かった。そこで,索引のクラスタ性と次の三つの前提を踏まえて,(1)~(5)の手順で性能改善を試みた。 ・それぞれの列値は均等に分布していると仮定する。 ・PJに参加しない従業員だけで構成される組織はないと仮定する。 ・全従業員が同じ曜日で働いていると仮定し,1か月は20日として計算する。 (1)SQL2のアクセス経路として,“従業員”テーブルを外表,“稼働実績”テーブルを内表とする入れ子ループ結合を想定する。 (2)このアクセス経路では,まず外表から指定した組織コードに対して,外表の副次索引1を用いて平均22行を読み込む。外表の副次索引1は低クラスタな索引なので,最大で【f】ページを読み込む。 (3)外表から読み込んだ従業員コード1件ごとに,内表の副次索引1を用いて下線①従業員1人当たりの稼働実績である1、200行を読み込み,行データの稼働年月日に対してBETWEEN述語を評価する。表3の稼働年月日列の列値個数は1、000(50か月分)なので,内表の集計対象の行は,1人当たり【g】行である。稼働実績を計上している従業員は組織当たり【h】人なので,集計対象の行は組織当たり【i】行となる。内表の副次索引1は高クラスタなので,読込みページ数は組織当たり最大【j】ページである。 (4)次に,読込みページ数を削減するために,{従業員コード,稼働年月日}をキーとする副次索引3を追加した場合の性能を検討した。この索引を使用した場合,副次索引1と比較すると,1か月分を索引で絞り込めるので,表からの読込み行数及び読込みページ数は【k】分の1に削減される。 (5)副次索引3の利用によって,表からの読込み行数及び読込みページ数を削減できるので,副次索引3を実装することにした。 設問1 〔テーブルの定義と実装〕について答えよ。 (1)“1.テーブルの定義”について,本文中の【a】~【e】に入れる適切な字句を答えよ。 (2)“2.テーブルへの行登録”において,“組織”テーブルへ行を挿入する場合,外部キーである組織長従業員コード及び上位組織コードのそれぞれについて,考慮すべき事項を一つずつ,25字以内で答えよ。 (3)Fさんは,図1中のテーブルのうち,“時間単価”テーブルの定義では,外部キーである“組織コード”のDELETEオプションをCASCADEに指定した。SET NULL又はRESTRICTを指定した場合,“時間単価”テーブルの定義時又は“組織”テーブルの行削除時に制約違反で失敗するおそれがあると考えたからである。なぜ制約に違反するのか,理由をそれぞれ45字以内で具体的に答えよ。 設問2 〔稼働計画の立案・稼働実績の確認〕について,表4中のSQL1の【ア】~【エ】に入れる適切な字句を答えよ。 設問3 〔問合せの性能改善〕について答えよ。 (1)統計情報について,表3の“稼働実績”テーブルの従業員コードの列値個数が表2の“従業員”テーブルの従業員コードの列値個数より少ないのはなぜか。本文中の用語を用いて,30字以内で答えよ。 (2)本文中の【f】に入れる適切な数値を答えよ。 (3)下線①について,稼働年月日列の列値個数が1、000であるにもかかわらず,従業員1人当たりの稼働実績の行数が1、000よりも多いのはなぜか。本文中の用語を用いて,30字以内で答えよ。 (4)本文中の【g】~【k】に入れる適切な数値を答えよ。
図1 主なテーブルのテーブル構造。組織,従業員,役職,時間単価,ランク,PJ,稼働計画,稼働実績の各テーブルと列構成を示す図。
図1 主なテーブルのテーブル構造。組織,従業員,役職,時間単価,ランク,PJ,稼働計画,稼働実績の各テーブルと列構成を示す図。
表1 主な列の意味・制約。上位組織コード,更新年月日,PM従業員コード,要員番号,計画時間,稼働時間の意味と制約を示す表。
表1 主な列の意味・制約。上位組織コード,更新年月日,PM従業員コード,要員番号,計画時間,稼働時間の意味と制約を示す表。
表2 “従業員”テーブルの主な統計情報・索引定義(一部省略)。従業員テーブルの行数,ページ当たり行数,列値個数,主索引及び副次索引1の定義を示す表。
表2 “従業員”テーブルの主な統計情報・索引定義(一部省略)。従業員テーブルの行数,ページ当たり行数,列値個数,主索引及び副次索引1の定義を示す表。
表3 “稼働実績”テーブルの主な統計情報・索引定義。稼働実績テーブルの行数,ページ当たり行数,列値個数,主索引,副次索引1及び副次索引2を示す表。
表3 “稼働実績”テーブルの主な統計情報・索引定義。稼働実績テーブルの行数,ページ当たり行数,列値個数,主索引,副次索引1及び副次索引2を示す表。
図2 “組織”テーブルを定義するCREATE TABLE文。組織テーブルの列定義,主キー,従業員及び組織を参照する外部キー制約を示すCREATE TABLE文。
図2 “組織”テーブルを定義するCREATE TABLE文。組織テーブルの列定義,主キー,従業員及び組織を参照する外部キー制約を示すCREATE TABLE文。
表4 稼働計画の立案及び稼働実績の確認を支援するSQL文の例。稼働計画候補を抽出するSQL1と,指定組織・期間の稼働時間を集計するSQL2,ホスト変数の注記を示す表。
表4 稼働計画の立案及び稼働実績の確認を支援するSQL文の例。稼働計画候補を抽出するSQL1と,指定組織・期間の稼働時間を集計するSQL2,ホスト変数の注記を示す表。
解き方のヒントを見る

依存関係と前提条件を整理する

この問題では、定義や処理の順序、データの格納状態など、答えを左右する前提が記述の中に含まれ得ます。結論を急がず、何が何に依存しているか、どの条件が明示されているかを先に書き出してから判断すると、見落としを防ぎやすくなります。

この問題で問われていること

問われている結論に影響する前提条件と依存関係を洗い出す観点に絞ります。どの要素が先に存在している必要があるか、データがどのような並びで保持されているとされているかなど、記述中の条件を一つずつ根拠として確認してください。

視点

制約や格納方式に関する問題では、一般論の知識だけで判断すると、問題ごとに設定された条件との食い違いに気づきにくくなります。まず、登場する要素どうしの参照や依存の向きを矢印などで整理します。次に、数量や配置に関する前提がどこに書かれているかを確認します。そのうえで、自分の判断がどの前提に基づいているのかを言葉にできるかを点検すると、根拠の弱い推測を避けられます。

確認ポイント

  • 登場する要素どうしの参照・依存の向きを図や矢印で書き出したか
  • 件数・サイズ・並び方など、判断に使う前提が記述のどこにあるかを確認したか
  • 自分の結論がどの前提に基づくかを一文で説明できるか
正解と解説を見る

解説

プロジェクト稼働管理システムを題材に、三つの力を問う問題です。一つ目は外部キー制約がテーブル定義順序・行登録順序・行削除に与える影響の理解、二つ目は外結合とウィンドウ関数を使ったSQLの設計、三つ目は索引のクラスタ性を踏まえた読込みページ数の見積りです。公式解答例では、組織長従業員コードの外部キーを後からALTER TABLEで追加すること、COALESCE(SUM(計画時間)、0)で順序付けすること、読込みページ数を22ページ・2、000ページと見積もることなどが示されています。

問題の全体像

E社がPJシステムをRDBMSで更改する事例です。組織・従業員・役職・ランク・時間単価・稼働計画・稼働実績などのテーブルが図1で与えられています。出題趣旨では、参照制約や索引のクラスタ性は初歩の概念である一方、他に及ぼす影響を正しく理解して実装することが求められるとされています。そのうえで、制約の設定が実装に与える影響を理解する能力と、索引や表の特性を性能見積りにつなげる能力が問われています。設問1は外部キーとテーブル定義・行登録・行削除の関係、設問2はSQL1の空欄補充、設問3はSQL2を入れ子ループ結合で処理したときの読込み行数・ページ数の見積りです。採点講評では全体の正答率は平均的とされ、RESTRICTの挙動、ウィンドウ関数の書き方、クラスタ性の性質の理解が課題として挙げられています。

設問1(1)(a)

図2の“組織”テーブルには外部キーが二つあります。組織長従業員コードは“従業員”を参照し、上位組織コードは“組織”自身を参照します。自己参照は定義中のテーブル自体を参照するので、他の表が未定義でも問題になりません。一方、“従業員”は未定義なので、この外部キー指定があると実行に失敗します。したがって、いったん削除する外部キーは組織長従業員コードです。公式解答例も組織長従業員コードとしています。

設問1(1)(b)

図1の参照関係を整理します。“ランク”は他を参照しません。“時間単価”はランクコードと組織コードを参照し、“役職”はランクコードを参照します。“従業員”は組織コードと役職コードを参照します。“組織”は①で定義済みなので、最初に実行できるのは参照先を持たない“ランク”です。公式解答例ではbはランクです。

設問1(1)(c)

“ランク”の次は、“組織”と“ランク”だけを参照する“時間単価”を定義できます。3番目が“役職”と決められているので、2番目は時間単価になります。公式解答例ではcは時間単価です。

設問1(1)(d)

“従業員”は“組織”と“役職”を参照するので、“役職”より後に定義する必要があります。したがって最後はdの従業員です。公式解答例も従業員としています。

設問1(1)(e)

すでに作成済みの“組織”テーブルに外部キー制約を後から加えるには、テーブル定義を変更する文を使います。“従業員”の定義後に組織長従業員コードの外部キーを追加するので、公式解答例ではALTER TABLEとしています。

設問1(2)(組織長従業員コード)

本文の行登録では、“組織”に先に行を挿入し、その後に“従業員”などへ挿入しています。“組織”の挿入時点では“従業員”に行がないため、組織長従業員コードに値を入れると参照先がなく制約違反になります。この列はNULLを許すので、挿入時はNULLにしておき、従業員の登録後に本文にあるUPDATE文で値を設定すればよいことになります。公式解答例は、挿入時にNULLを設定しておくことです。答案では、NULLを設定する点と挿入時である点を25字以内に収めます。

設問1(2)(上位組織コード)

上位組織コードは“組織”自身を参照するため、上位組織の行が先に存在しなければ下位組織を挿入できません。表1から、最上位組織の上位組織コードはNULLです。したがって最上位組織から始めて、上位から下位へ順に登録する必要があります。公式解答例は、最上位組織から上位順に組織を登録することです。

設問1(3)(SET NULL)

“時間単価”の主キーは{ランクコード、 組織コード、 適用開始年月日}なので、組織コードは主キーの一部です。主キー列にはNULLを設定できません。組織削除時に組織コードをNULLに変えるSET NULLは主キーの制約と矛盾するため、定義時または削除時に失敗するおそれがあります。公式解答例では、“時間単価”テーブルの組織コードは主キーの一部でありNULLに変更できないからとしています。答案では、主キーの一部であることとNULLにできないことの2点を入れます。

設問1(3)(RESTRICT)

時間単価はランク別・組織別・年月日別に決めているので、組織が廃止されてPJ管理に不要と判断されても、その組織コードを持つ時間単価の行が残っていることがあります。RESTRICTでは参照している行が存在すると参照先の削除が拒否されるため、“組織”の行を削除するときに失敗します。公式解答例では、“時間単価”テーブルに同じ組織コードの行が存在する場合があるからとしています。採点講評では正答率がやや低かったとされ、RESTRICTが参照先の削除を防ぐという挙動と、関与するのが“時間単価”と“組織”である点を読み取ってほしいと述べられています。

設問2(ア)

SQL1の目的には、組織ごとに計画時間の少ない順に順序付けして1~3の番号を付けるとあります。NTILE(3)をどのグループの中で適用するかはPARTITION BYで指定するので、区切りは組織コードです。公式解答例ではアは組織コードです。

設問2(イ)

順序付けの基準は計画時間の合計です。ただし、稼働計画にない従業員は外結合によってSUM(計画時間)がNULLになります。目的には計画時間をゼロで表示するとあるので、ゼロとして並べる必要があります。SELECT句と同じ式を使い、公式解答例ではCOALESCE(SUM(計画時間)、0)としています。この式はNTILEとRANKの両方のORDER BYで使います。採点講評では正答率がやや低く、ウィンドウ関数の書き方と集計条件の読み取りが求められると指摘されています。

設問2(ウ)

稼働計画に登録されていない従業員も含めるため、行を必ず残す左側の表(A)は従業員の一覧である必要があります。WHERE句の役職コードも“従業員”の列です。公式解答例ではウは従業員です。

設問2(エ)

右側の表(B)は、従業員コード・計画年・計画月で結合し、計画時間を持つ表です。これは稼働計画です。計画年・計画月の条件をWHERE句ではなくON句に書いているので、計画のない従業員も外結合で残ります。公式解答例ではエは稼働計画です。

設問3(1)

表2では従業員コードの列値個数が8、800、表3では8、000です。業務の概要2(1)に、PJに参加していない従業員も一部いるとあります。そうした従業員は稼働実績を入力しないので、“稼働実績”には現れません。公式解答例は、PJに参加していない従業員も一部いるからです。30字以内という条件なので、本文の表現をそのまま使うのが確実です。

設問3(2)

外表の“従業員”8、800行を組織コードの列値個数400で割ると、1組織当たり平均22行になります。副次索引1は低クラスタなので行へのアクセスはランダムになり、最悪の場合は1行ごとに別のページを読みます。そのため最大で22ページです。公式解答例ではfは22です。採点講評では、低クラスタな索引ではアクセスがランダムになるという性質の理解が求められています。

設問3(3)

稼働実績の9、600、000行を従業員コードの列値個数8、000で割ると、1人当たり1、200行です。稼働年月日は1、000種類しかないので、同じ日付に複数の行を持つ場合があることになります。業務の概要2(4)に、従業員は同じ日に複数PJの稼働時間を入力できるとあります。公式解答例は、従業員は同じ日に複数PJの稼働時間を入力できるからです。

設問3(4)(g)

1人当たりの1、200行は50か月分です。SQL2の対象は1か月分なので、1、200÷50=24行になります。1か月20日と見れば、1日当たり1.2行です。公式解答例ではgは24です。

設問3(4)(h)

稼働実績を計上している従業員は8、000人で、組織は400です。前提により、PJに参加しない従業員だけで構成される組織はなく、列値も均等に分布しています。したがって8、000÷400=20人です。公式解答例ではhは20です。外表から読む22人のうち2人は、実績行を持たないことになります。

設問3(4)(i)

組織当たりの集計対象の行は、20人×24行=480行です。公式解答例ではiは480です。

設問3(4)(j)

副次索引1はキーが従業員コードだけなので、1人当たり1、200行、つまり50か月分をすべて読んでからBETWEENで絞り込みます。本文の調査結果では、従業員当たり1か月分の行は高々2ページに収まっており、副次索引1は高クラスタです。そのため1人当たり最大2ページ×50か月=100ページ、組織当たりでは100ページ×20人=2、000ページになります。公式解答例ではjは2、000です。1、200行÷100行/ページのように単純に割るのではなく、本文に示された1か月当たり最大2ページという条件を使う点が重要です。

設問3(4)(k)

副次索引3のキーは{従業員コード、 稼働年月日}なので、索引の段階で対象の1か月分に絞り込めます。副次索引1では50か月分を読んでいたので、表から読む行数とページ数はいずれも50分の1になります(1人当たり1、200行→24行、100ページ→2ページ)。公式解答例ではkは50です。

学習のポイント

参照関係からテーブルの依存順序を組み立てる練習と、ON DELETEの各オプションの挙動を主キー制約と合わせて理解することが大切です。さらに、統計情報から行数とページ数を段階的に計算する手順を身に付けましょう。採点講評では、設問1(3)のRESTRICT、設問2のイ、設問3の(2)と(4)の正答率が低かったと指摘されています。

出典:独立行政法人 情報処理推進機構(IPA)令和6年度秋期 データベーススペシャリスト試験 午後Ⅰ 問3(公式資料:問題冊子(PDF) / 解答例 / 採点講評)

関連する過去問一覧

IPA Advancedは非公式の学習サイトです。解説にはAIによる補助生成を含む場合があります。公式の問題冊子・解答例・採点講評を優先し、誤りは確認後に訂正します。運営・編集方針