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

令和7年度秋期 データベーススペシャリスト 午後Ⅰ 問3 オフィスじゅう器メーカーの在庫管理システムのデータベース実装

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

問題

問3 オフィスじゅう器メーカーの在庫管理システムのデータベース実装に関する次の記述を読んで,設問に答えよ。 オフィスじゅう器メーカーのY社は,RDBMSを用いた在庫管理システムを稼働させてから10年が経ち,システム更改を予定している。そこで,Kさんが改善点の検討を任された。 〔RDBMSの主な仕様〕 1. アクセス経路 (1)アクセス経路は,RDBMSによって表探索又は索引探索に決められる。表探索では,索引を使わずに先頭ページから順に全行を読み込む。索引探索では,索引によって絞り込んでから表の行を読み込む。 (2)索引探索を選択するためには,WHERE句又はON句のANDだけで結ばれた一つ以上の等値比較の述語の対象列が,索引キーの全体又は先頭から連続した一つ以上の列に一致していなければならない。 (3)索引探索のとき,SELECT文で取得対象とする列と,探索条件で絞込みに利用する列が,索引キーに全て含まれている場合は,表の行を読み込まずに,索引へのアクセスだけで結果を返す。 2. 排他制御 (1)排他制御では行単位で共有ロック又は専有ロックを取得する。共有ロックを取得している間,他のトランザクションから対象行への共有ロックの取得は可能であり,専有ロックの取得は共有ロックの解放待ちとなる。専有ロックを取得している間,他のトランザクションから対象行への共有ロック及び専有ロックの取得は,専有ロックの解放待ちとなる。 (2)アクセス経路に従って,探索した行をロックの対象とする。 (3)SELECT文にFOR UPDATE句を指定すると,ISOLATIONレベルにかかわらず,対象行の専有ロックを取得し,トランザクション終了時に解放する。 3. 時刻印型の列 (1)テーブル定義で,時刻印型の列(以下,TS列という)のDEFAULT句にCURRENT_TIMESTAMPを指定することで,行が挿入されたとき,TS列に現在時刻印を自動的に設定することができる。 (2)行が更新されたときにTS列をCURRENT_TIMESTAMPで更新するトリガーを定義することで,TS列を現在時刻印で自動的に更新することができる。 〔在庫管理システムの概要〕 1. テーブル構造 主なテーブルのテーブル構造を図1に示す。主キーには主索引が定義されている。 2. 業務の概要 (1)各地の生産拠点には,組立工場と,これに隣接する倉庫がある。 (2)倉庫からの部品の出庫には,倉庫から隣接する組立工場に出庫する場合と,倉庫から他の生産拠点の倉庫に出庫する場合がある。 (3)倉庫は,倉庫コードで識別する。部品は,部品番号で識別する。 (4)部品の在庫は,倉庫と部品の組合せで管理する。倉庫内に存在する在庫の数量を在庫数量と呼ぶ。このうち,出庫対象として引き当てた数量を,引当済在庫数量と呼ぶ。また,在庫数量から引当済在庫数量を引いた数量を,出庫可能在庫数量と呼ぶ。 (5)部品の出庫は,出庫要求,在庫引当,出庫,在庫反映の流れで,それぞれのアプリケーションプログラム(以下,APという)を用いて処理し,“出庫”テーブルに処理状況を記録する。 ・出庫要求とは,部品の出庫要求を受け付けて,“出庫”テーブルに行を追加する処理である。処理状況を‘要求発生’にする。 ・在庫引当とは,出庫要求に応じて倉庫内の在庫を引き当てる処理である。指定された倉庫コード,部品番号,出庫数量の出庫が可能かどうかチェックし,出庫が可能であれば“在庫”テーブルの引当済在庫数量を更新し,処理状況を‘引当実施’にする。 ・出庫とは,倉庫から在庫の引当ができた部品を出す処理である。処理状況を‘出庫済’にする。 ・在庫反映とは,処理状況が‘出庫済’の全ての出庫を対象に,“在庫”テーブルの在庫数量及び引当済在庫数量から引き落として,処理状況を‘在庫反映済’にする一括処理である。“在庫反映”APは,毎日の業務終了時に実行する。 (6)入庫とは,部品メーカーから納品された,又は他の生産拠点の倉庫から出庫された部品を倉庫に入れることである。運ばれてきた部品を倉庫内の集積所に蓄積し,当日の入庫予定分がそろったら順に入庫を処理し,在庫を更新する。入庫による在庫の更新は,在庫反映と同時に実施しない。 〔在庫履歴分析手段の見直し〕 日別の在庫数量を集計するAPを用いて,在庫数量の日別の推移状況を分析している。このAPでは,“在庫”,“出庫”及び“入庫”テーブルを参照して,在庫数量を集計しており,データ量の増加に伴って処理時間が長くなっていた。この対策として,図2に示す“在庫履歴”テーブルを作成して,在庫数量の推移を蓄積していくことにした。 Kさんは,“在庫”,“出庫”及び“入庫”テーブルからこれまでの在庫履歴を作成する方法を検討した。 全ての倉庫の全ての部品について,在庫履歴を作成する初日時点の在庫数量の行をあらかじめ作成しておき,在庫履歴を蓄積する年月日分繰り返し実行するSQL1を設計した。 また,区間数7の中央移動平均のグラフを作成したいとの要望があった。区間数7の中央移動平均は,ある年月日とその前後3日間の計7日間の平均値である。計7日間のデータがそろわない期間は対象外である。Kさんは,作成した在庫履歴のデータから区間数7の中央移動平均用データを加工するSQL2を設計した。 設計したSQL文を,表1に示す。 〔トランザクションの排他制御の見直し〕 既存システムの実行ログを分析すると,複数の“在庫引当”APが,“在庫”テーブルの同じ行に対して同時実行されたときに,デッドロックによってAPのリトライが発生していることが判明した。“在庫引当”APの処理の流れとSQL文を図3に示す。ISOLATIONレベルはREPEATABLE READで実行している。 Kさんはデッドロックの原因を調査し,上司であるL氏と対応について議論した。 L氏:デッドロックの原因は何でしょうか。 Kさん:ある“在庫引当”APが□j□で共有ロックを取得した後,□k□で専有ロックを取得し直す前に,別の“在庫引当”APが□j□で共有ロックを取得してしまい,互いに専有ロックを取得しようとしてロックの解放待ちになっていました。 L氏:どのような改善案がありますか。 Kさん:“在庫”テーブルの同じ行に対して,“在庫引当”APが同時実行されないように最終更新TS列で制御する案があります。“在庫引当”APを次のように変更します。①のSELECT文で□l□するように変更し,①の後にCOMMIT文を追加します。②のUPDATE文のWHERE句に,□m□ことを条件として追加します。②の後に,②のUPDATE文で該当する行がなかったら,□n□に戻る制御を追加します。 L氏:その案ではAPの大幅な変更が必要になります。変更を最小限にとどめる方法はありますか。 Kさん:ISOLATIONレベルをREAD COMMITTEDに変更して,□j□の共有ロックがすぐに解放されるようにする案もあります。 L氏:単純にREAD COMMITTEDに変更すると,引当済在庫数量が不正になってしまうおそれがあります。同じ倉庫の同じ部品に対して,“在庫引当”APが複数同時に実行されるとき,それぞれの要求する出庫数量の合計が,□o□していると,引当済在庫数量が不正になってしまいます。ISOLATIONレベルを変更しない方法はありますか。 Kさん:①のSELECT文に,□p□する案があります。 〔索引の見直し〕 毎日の業務終了時に実行される“在庫反映”APの処理時間の短縮要望を受け,Kさんが対策を検討した。その結果,出庫倉庫コードと部品番号の組合せの値の範囲で分割し,分割した値の範囲それぞれを各プロセスに配分して並列実行するように変更することにした。変更後の“在庫反映”APの処理の流れを図4に示す。ISOLATIONレベルはREPEATABLE READで実行する。 これを確認したL氏は,索引の見直しを指示した。 L氏:“□q□”テーブルの□r□列と□s□列の組合せをこの順で索引キーとする複数列索引を定義しておく必要があります。この索引を定義していないと,自プロセスの対象行かどうかを判定するための参照が表探索となります。その場合,他APが□t□した行を参照しようとして□u□が生じた結果,処理時間が長くなるおそれがあります。デッドロックが発生しないかの検証も必要です。 Kさん:処理要否の判定も,表の行の読込みを不要にして性能を向上させるために,“□q□”テーブルの□v□列もこの複数列索引の索引キーに加えてもよいでしょうか。 L氏:そのメリットと,そうすることで“□q□”テーブルを更新するAPが,__①索引の更新頻度の増加によって性能が低下する__デメリットとのトレードオフを検証してください。 設問1 〔在庫履歴分析手段の見直し〕について答えよ。 (1)表1中の□a□〜□i□に入れる適切な字句又は数値を答えよ。 (2)表1中のSQL2の下線アについて,CASE式のELSE句で中央移動平均をNULLにする理由を25字以内で答えよ。 設問2 〔トランザクションの排他制御の見直し〕について答えよ。 (1)本文中の□j□,□k□に入れる適切な数字を,図3中の①〜④の中から選んで答えよ。 (2)本文中の□l□,□m□に入れる適切な字句を答えよ。また,□n□に入れる適切な数字を,図3中の①〜④の中から選んで答えよ。 (3)本文中の□o□に入れる引当済在庫数量の不正を引き起こす条件を答えよ。 (4)本文中の□p□に入れる適切な変更内容を答えよ。 設問3 〔索引の見直し〕について答えよ。 (1)本文中の□q□〜□v□に入れる適切な字句を答えよ。 (2)本文中の下線①について,索引キーに□v□列を加えることで索引の更新頻度が増加するのはなぜか。□v□列の特徴に着目して,30字以内で具体的に答えよ。
図1 主なテーブルのテーブル構造。
図1 主なテーブルのテーブル構造。
図2 “在庫履歴”テーブルのテーブル構造。
図2 “在庫履歴”テーブルのテーブル構造。
表1 在庫履歴用のSQL文(未完成)。
表1 在庫履歴用のSQL文(未完成)。
図3 “在庫引当”APの処理の流れとSQL文。
図3 “在庫引当”APの処理の流れとSQL文。
図4 変更後の“在庫反映”APの処理の流れ。
図4 変更後の“在庫反映”APの処理の流れ。
解き方のヒントを見る

処理の目的と前提を対応づける

SQLの実行や同時利用、索引の検討では、個別の用語を暗記するより、何を守り、何を効率化したい処理なのかを先に整理して、設問に示された条件や制約と対応づけて考えます。

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

一つの観点として、各記述が示す仕組みの目的と、成立するための前提条件が対応しているかに注目し、処理の対象・順序・影響範囲を問題文に沿って丁寧に確認してください。

視点

処理を考えるときは、まず達成したい目的を明確にし、その目的に関係する対象と前提を整理します。次に、記述がその関係を一貫して説明しているかを、用語の印象ではなく条件の対応で確かめます。

確認ポイント

  • 記述が前提としている対象と条件を確認する
  • 目的と処理の関係が同じ観点で説明されているか確認する
  • 結果だけでなく影響範囲と順序にも注目する
正解と解説を見る

解説

在庫履歴の効率的な作成、中央移動平均の算出、在庫引当時のデッドロック回避、並列処理に適した索引設計を問う問題です。

問題の全体像

Y社は、10年間稼働した在庫管理システムを更改しようとしている。問題は、既存の在庫・出庫・入庫データを履歴表へ効率的に蓄積するSQL、7日間の中央移動平均、在庫引当APで発生するデッドロック、在庫反映APの並列化に伴う索引設計を扱う。出題の狙いは、SQLの構文だけでなく、業務処理の流れ、ロックの取得・解放、索引の探索条件と更新負荷を関連付けて改善策を考えることにある。

設問1(1)

SQL1では、前日の在庫数量を基準に、当日の出庫を減算し、当日の入庫を加算する。したがって、出庫状況と入庫状況の集計はそれぞれ SUM(出庫数量)、SUM(入庫数量)となり、結合後に参照する別名は当日出庫数量、当日入庫数量となる。SQL2では、在庫履歴を倉庫コードと部品番号ごとに分け、履歴年月日順に7行の窓を作る。中央の年月日の前後3日を含めるため、範囲は3 PRECEDING AND 3 FOLLOWINGであり、平均対象は在庫数量です。よって、公式解答例は a=SUM(出庫数量)、b=SUM(入庫数量)、c=当日出庫数量、d=当日入庫数量、e=AVG(在庫数量)、f=倉庫コード、 部品番号、g=履歴年月日、h=3、i=3としている。

設問1(2)

中央移動平均は、対象日の前後3日を含む計7日間のデータが必要です。問題文で7日間のデータがそろわない期間は対象外と明記されているため、COUNT(*) OVER 移動平均区間 が7未満の場合は、CASE式のELSE句でNULLにする。25字以内では「計7日間のデータがそろわない期間は対象外だから」とまとめられる。

設問2(1)

図3の①は在庫数量と引当済在庫数量をSELECTして出庫可能在庫数量を判定する処理であり、REPEATABLE READでは読み取った行の共有ロックが保持される。その後、②で引当済在庫数量をUPDATEするため専有ロックを取得し直す。別APも①で同じ行を共有ロックしていると、互いに②の専有ロックを待つためデッドロックになる。したがって、j=①、k=②です。

設問2(2)

最終更新TS列を利用する案では、①のSELECTで現在のTS値も読み取り、①の後にCOMMITして共有ロックを解放する。②のUPDATEは、読み取ったTS値と現在のTS値が一致する場合だけ実行することで、他APによる更新を検出する。更新対象がなければ、処理をやり直す必要があるため、図3の①に戻る。公式解答例は、l=最終更新TS列の値も取得、m=最終更新TS列が①で取得した値と一致する、n=①としている。

設問2(3)

READ COMMITTEDでは①の共有ロックが早く解放されるため、複数APが同じ在庫行を読み取ってから更新する可能性がある。その場合、それぞれが同時点の在庫数量を基に出庫可能在庫数量を判定し、要求数量の合計が出庫可能在庫数量を超過しても更新できると、引当済在庫数量が過大になる。したがって、oは「出庫可能在庫数量を超過」です。

設問2(4)

ISOLATIONレベルを変更せず、①で読み取った直後から対象行を専有ロックすれば、別APが同じ行を同時に読み取ることを防げる。問題文の仕様ではSELECT文にFOR UPDATE句を指定すると対象行の専有ロックを取得できるため、pは「FOR UPDATE句を指定」です。

設問3(1)

並列化後は、各プロセスが出庫倉庫コードと部品番号の範囲を担当し、出庫表の処理状況を確認して対象行を更新する。処理要否の判定を索引探索にするには、WHERE条件の列を先頭から連続して索引キーに含める必要があるため、q=出庫、r=出庫倉庫コード、s=部品番号となる。他APが処理を進めると処理状況を更新するのでt=更新であり、表探索でその行を参照すると、他APの更新ロックによりu=ロックの解放待ちが起こり得る。SELECTで処理状況まで索引に含めれば表の行を読まずに判定できるため、v=処理状況です。

設問3(2)

処理状況列を索引キーに加えると、出庫の処理が進むたびに処理状況の値が変化する。そのたびに索引キーの値も変わり、索引を更新する必要があるため、更新頻度が増加する。30字以内では「出庫の処理が進むたびに索引キーの値が変わるから」と書ける。

学習のポイント

集計SQL、ウィンドウ関数、楽観的排他制御、索引更新コストを一連の業務要件と結び付けて学ぶ。

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

関連する過去問一覧

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