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

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

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

問題

問3 データベースの実装と性能に関する次の記述を読んで、設問に答えよ。 事務用品を関東地方で販売するC社は、販売管理システム(以下、システムという)にRDBMSを用いている。 〔RDBMSの仕様〕 1.表領域 (1)テーブル及び索引のストレージ上の物理的な格納場所を、表領域という。 (2)RDBMSとストレージとの間の入出力単位を、ページという。同じページに、異なるテーブルの行が格納されることはない。 2.再編成、行の挿入 (1)テーブルを再編成することで、行を主キー順に物理的に並び替えることができる。また、再編成するとき、テーブルに空き領域の割合(既定値は30%)を指定した場合、各ページ中に空き領域を予約することができる。 (2)INSERT文で行を挿入するとき、RDBMSは、主キー値の並びの中で、挿入行のキー値に近い行が格納されているページを探し、空き領域があればそのページに、なければ表領域の最後のページに格納する。最後のページに空き領域がなければ、新しいページを表領域の最後に追加し、格納する。 〔業務の概要〕 1.顧客、商品、倉庫 (1)顧客は、C社の代理店、量販店などで、顧客コードで識別する。顧客にはC社から商品を届ける複数の発送先があり、顧客コードと発送先番号で識別する。 (2)商品は、商品コードで識別する。 (3)倉庫は、1か所である。倉庫には複数の棚があり、一連の棚番号で識別する。商品の容積及び売行きによって、一つの棚に複数種類の商品を保管することも、同じ商品を複数の棚に保管することもある。 2.注文の入力、注文登録、在庫引当、出庫指示、出庫の業務の流れ (1)顧客は、C社が用意した画面から注文を希望納品日、発送先ごとに入力し、C社のEDIシステムに蓄える。注文は、単調に増加する注文番号で識別する。注文する商品の入力順は自由で、入力後に商品の削除も同じ商品の追加もできる。 (2)C社は、毎日定刻(9時と14時)に注文を締める。EDIシステムに蓄えた注文をバッチ処理でシステムに登録後、在庫を引き当てる。 (3)出庫指示書は、当日が希望納品日である注文ごとに作成し、倉庫の出庫担当者(以下、ピッカーという)を決めて、作業開始の予定時刻までにピッカーの携帯端末に送信する。携帯端末は、棚及び商品のバーコードをスキャンする都度、システム中のオンラインプログラムに電文を送信する。 (4)出庫は、ピッカーが出庫指示書の指示に基づいて1件の注文ごとに行う。 ①棚の通路の入口で、携帯端末から出庫開始時刻を伝える電文を送信する。 ②棚番号の順に進みながら、指示された棚から指示された商品を出庫する。 ③商品を出庫する都度、携帯端末で棚及び商品のバーコードをスキャンし、商品を台車に積む。ただし、一つの棚から商品を同時に出庫できるのは1人だけである。また、順路は1方向であるが、通路は追い越しができる。 ④台車に積んだ全ての商品を、指定された段ボール箱に入れて梱包する。 ⑤別の携帯端末で印刷したラベルを箱に貼り、ラベルのバーコードをスキャンした後、梱包した箱を出荷担当者に渡すことで1件の注文の出庫が完了する。 〔システムの主なテーブル〕 システムの主なテーブルのテーブル構造を図1に、主な列の意味・制約を表1に示す。主キーにはテーブル構造に記載した列の並び順で主索引が定義されている。 図1 テーブル構造(一部省略) 表1 主な列の意味・制約(一部省略) 〔システムの注文に関する主な処理〕 注文登録、在庫引当、出庫指示の各処理をバッチジョブで順に実行する。出庫実績処理は、携帯端末から電文を受信するオンラインプログラムで実行する。バッチ及びオンラインの処理のプログラムの主な内容を、表2に示す。 表2 処理のプログラムの主な内容 注記1 二重引用符で囲んだ名前は、テーブル名を表す。 注記2 いずれの処理も、ISOLATIONレベルはREAD COMMITTEDで実行する。 〔ピーク日の状況と対策会議〕 注文量が特に増えたピーク日に、朝のバッチ処理が遅延し、出庫作業も遅延する事態が発生した。そこで、関係者が緊急に招集されて会議を開き、次のように情報を収集し、対策を検討した。 1.システム資源の性能に関する基本情報 次の情報から特定のシステム資源に致命的なボトルネックはないと判断した。 (1)ページングは起きておらず、CPU使用率は25%程度であった。 (2)バッファヒット率は95%以上で高く、ストレージの入出力処理能力(IOPS、帯域幅)には十分に余裕があった。 (3)ロック待ちによる大きな遅延は起きていなかった。 2.再編成の要否 アクセスが多かったのは「注文明細」テーブルであった。この1年ほど行の削除は行われず、再編成も行っていないことから、時間が掛かる行の削除を行わず、直ちに再編成だけを行うことが提案されたが、この提案を採用しなかった。なぜならば、当該テーブルへの行の挿入では予約された空き領域が使われないこと、かつ空き領域の割合が既定値だったことで、割り当てたストレージが満杯になるリスクがあると考えられたからである。 3.バッチ処理のジョブの多重化 バッチ処理のスループット向上のために、ジョブを注文番号の範囲で分割し、多重で実行することが提案されたが、デッドロックが起きるリスクがあると考えられた。そこで、どの処理とどの処理との間で、どのテーブルでデッドロックが起きるリスクがあるか、表3のように整理し、対策を検討した。 表3 デッドロックが起きるリスク(未完成) 注記 ケース3は、ジョブの進み具合によって異なる処理のジョブが同時に実行される場合を表す。 4.出庫作業の遅延原因の分析 出庫作業の現場の声を聞いたところ、特定の棚にピッカーが集中し、棚の前で待ちが発生したらしいことが分かった。そこで、棚の前での待ち時間と棚から商品を取り出す時間の和である出庫間隔時間を分析した。出庫間隔時間は、ピッカーが出庫指示書の1番目の商品を出庫する場合では当該注文の出庫開始時刻からの時間、2番目以降の商品の出庫の場合では一つ前の商品の出庫時刻からの時間である。出庫間隔時間が長かった棚と商品が何かを調べたSQL文の例を表4に、このときの棚と商品の配置、及びピッカーの順路を図2に示す。 表4 SQL文の例(未完成) 図2 棚と商品の配置、及びピッカーの順路(一部省略) 表4中の【x】に、B.出庫番号、A.ピッカーID、B.棚番号のいずれか一つを指定することが考えられた。分析の目的が、特定の棚の前で長い待ちが発生していたことを実証することだった場合、【あ】を指定すると、棚の前での待ち時間を含むが、商品の梱包及び出荷担当者への受渡しに掛かった時間が含まれてしまう。【い】を指定すると、棚の前での待ち時間が含まれないので、分析の目的を達成できない。 分析の結果、棚3番の売行きの良い商品S3(商品コード)の出庫で長い待ちが発生したことが分かった。そこで、【下線:出庫作業の順路の方向を変えない条件で、多くのピッカーが同じ棚(ここでは、棚3番)に集中しないように出庫指示を作成する対策】が提案された。しかし、この対策を適用すると、表3中のケース2でデッドロックが起きるリスクがあると予想した。 例えば、あるピッカーに、1番目に棚3番の商品S3を出庫し、2番目に棚6番の商品S6を出庫する指示を作成するとき、別のピッカーには、1番目に棚【う】の商品【え】を出庫し、2番目に棚【お】の商品【か】を出庫する指示を同時に作成する場合である。 設問1 「2.再編成の要否」について答えよ。 (1)注文登録処理が「注文明細」テーブルに行を挿入するとき、再編成で予約した空き領域が使われないのはなぜか。行の挿入順に着目し、理由をRDBMSの仕様に基づいて、40字以内で答えよ。 (2)行の削除を行わず、直ちに再編成だけを行うと、ストレージが満杯になるリスクがあるのはなぜか。前回の再編成の時期及び空き領域の割合に着目し、理由をRDBMSの仕様に基づいて、40字以内で答えよ。 設問2 「3.バッチ処理のジョブの多重化」について答えよ。 (1)表3中の【a】~【c】に入れる適切な理由を、それぞれ30字以内で答えよ。ここで、在庫は適正に管理され、欠品はないものとする。 (2)表3中のケース1のリスクを回避するために、注文登録処理又は在庫引当処理のいずれかのプログラムを変更したい。どちらかの処理を選び、選んだ処理の処理名を答え、プログラムの変更内容を具体的に30字以内で答えよ。ただし、コミット単位とISOLATIONレベルを変更しないこと。 設問3 「4.出庫作業の遅延原因の分析」について答えよ。 (1)本文中の【あ】~【か】に入れる適切な字句を答えよ。 (2)下線の対策を適用した場合、表3中のケース2で起きると予想したデッドロックを回避するために、出庫指示処理のプログラムをどのように変更すべきか。具体的に40字以内で答えよ。ただし、コミット単位とISOLATIONレベルを変更しないこと。
図1 テーブル構造(一部省略)。システムで扱う顧客、商品、在庫、棚、注文、出庫などの主要テーブルと主キー列を列挙した構造図。
図1 テーブル構造(一部省略)。システムで扱う顧客、商品、在庫、棚、注文、出庫などの主要テーブルと主キー列を列挙した構造図。
表1 主な列の意味・制約(一部省略)。棚番号、注文状態、出庫時刻について、それぞれの意味や値の制約を示す表。
表1 主な列の意味・制約(一部省略)。棚番号、注文状態、出庫時刻について、それぞれの意味や値の制約を示す表。
表2 処理のプログラムの主な内容。注文登録、在庫引当、出庫指示、出庫実績のバッチ及びオンライン処理の内容と、二つの注記を示す表。
表2 処理のプログラムの主な内容。注文登録、在庫引当、出庫指示、出庫実績のバッチ及びオンライン処理の内容と、二つの注記を示す表。
表3 デッドロックが起きるリスク(未完成)。在庫引当、出庫指示の処理間で、在庫、棚別在庫、注文明細に関するデッドロックリスクと判断理由を記入する表。
表3 デッドロックが起きるリスク(未完成)。在庫引当、出庫指示の処理間で、在庫、棚別在庫、注文明細に関するデッドロックリスクと判断理由を記入する表。
表4 SQL文の例(未完成)。出庫間隔時間を集計するWITH句、LAG関数、GROUP BY及びORDER BYを含む未完成SQL文の例。
表4 SQL文の例(未完成)。出庫間隔時間を集計するWITH句、LAG関数、GROUP BY及びORDER BYを含む未完成SQL文の例。
図2 棚と商品の配置、及びピッカーの順路(一部省略)。棚番号と商品コードの配置、通路入口、出庫作業の一方向の順路、梱包及び受渡し場への経路を示す図。
図2 棚と商品の配置、及びピッカーの順路(一部省略)。棚番号と商品コードの配置、通路入口、出庫作業の一方向の順路、梱包及び受渡し場への経路を示す図。
解き方のヒントを見る

現象と原因の対応を記述から確かめる

性能低下や待ちの問題を検討するときは、観察された現象と、その原因として考えられる要因とを切り分け、問題中に示された条件や事実だけを根拠に両者の対応関係を一つずつ確かめる姿勢が役立ちます。

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

確認すべき観点は一つ、各主張が述べている事柄が、問題中で与えられた前提・条件・データと矛盾なく結び付くかどうかです。一般論として正しそうに見えるかではなく、この問題の状況に当てはまるかを基準に判断します。

視点

運用中のシステムで起きる遅延や停止は、どの層で何が起きているかを区別して捉えると整理しやすくなります。ある対策や説明が妥当かどうかは、それが作用する範囲と、実際に起きている事象の原因とが一致しているかで決まります。問題中の数値・時系列・処理条件などを根拠として押さえ、書かれていない事情を推測で補わないことが大切です。

確認ポイント

  • 問題中で示された現象・データ・条件を、推測を交えずに書き出したか
  • 検討中の主張や対策が、どの事象に作用するものかを自分の言葉で説明できるか
  • その主張が問題の前提と食い違う点や、根拠が示されていない点がないか
正解と解説を見る

解説

C社の販売管理システムでピーク日にバッチと出庫作業が遅延した事例です。三つの観点が問われます。一つ目は、行の削除をせずに再編成だけを行うと、なぜストレージが満杯になるリスクがあるか(RDBMSの挿入仕様と空き領域)。二つ目は、ジョブを多重化したときのデッドロックのリスク(テーブルごとの更新順序と、注文番号の範囲による分割)。三つ目は、LAG関数を使った出庫間隔時間の分析と、棚への集中を避ける対策で生じる新たなデッドロックのリスクです。どの設問も、本文の仕様と表2の処理内容を根拠に説明できます。

問題の全体像

事務用品を販売するC社では、注文登録・在庫引当・出庫指示をバッチで順に実行し、出庫実績はオンラインで処理しています。注文量が特に多いピーク日に、朝のバッチと出庫作業が遅延しました。CPU、I/O、ロック待ちに致命的なボトルネックはなく、対策会議では次の三つを検討しています。(1)「注文明細」の再編成を今すぐ行うべきか、(2)ジョブを注文番号の範囲で分割して多重実行するとデッドロックのリスクがあるか、(3)出庫の遅延原因をSQLでどう分析し、どんな対策を取るか。公式解答例の出題趣旨では、性能低下への初期対応の考え方、ウィンドウ関数を使ったSQL設計の理解、そしてリスクを予測して対策の採否を決める能力を問うとしています。

設問1(1)

着目点は二つあります。一つはRDBMSの仕様2(2)で、挿入行は「主キー値の並びでキー値が近い行があるページ」に空きがあればそこに入り、なければ表領域の最後のページに入ります。もう一つは、「注文明細」の主キーが(注文番号、 注文明細番号)で、注文番号が単調に増加することです。新しく挿入する行のキーは常に既存の最大値より大きいので、過去の注文の行があるページ(再編成で空き領域を予約したページ)の近くには挿入されません。行は最後のページに格納され続けます。公式解答例では、「主キーが単調増加するので過去の注文番号の近くに挿入しない」または「主キーの昇順に挿入すると最後のページに格納を続ける」という趣旨を示しています。40字以内に収めるには、「単調増加(昇順)の挿入」と「予約した空き領域のある過去のページではなく最後のページに入る」の二点を押さえます。

設問1(2)

本文によると、この1年ほどは再編成も行の削除もしていません。前回の再編成より後に追加された行は、設問1(1)のとおり最後のページに空きなく詰めて格納されています。この状態で空き領域の割合を既定値(30%)のまま再編成すると、この1年に追加したページの一つ一つに30%の空き領域が予約されます。同じ行数を格納するのに必要なページ数がその分増え、しかも予約した空き領域は今後の挿入でも使われません。公式解答例では「再編成後に追加した各ページで既定の空き領域分のページが増える」という趣旨です。答案では「前回の再編成以降に追加したページ」と「既定30%の空き領域の分だけページ数が増える」を結び付けて書きます。採点講評では(1)より(2)の正答率が低く、再編成で空き領域を予約する必要があるとは限らないこと、緊急時ほどリスクを慎重に予測することを求めています。

設問2(1)(a)

ケース1は、在庫引当ジョブ同士が「在庫」テーブルでぶつかる場合です。表2によると、在庫引当は「注文明細」を主キー(注文番号、 注文明細番号)の順に読み、その順に「在庫」を更新し、コミットは注文ごとです。注文明細番号は顧客が入力した順に付くので、商品コードの順序はそろっていません。そのため、あるジョブは商品S1→S2の順、別のジョブはS2→S1の順に「在庫」の行をロックすることがあり、互いの行を待ってデッドロックになり得ます。公式解答例では「異なる商品の“在庫”を逆順で更新することがあり得るから」という趣旨です。

設問2(1)(b)

ケース2は、出庫指示ジョブ同士が「棚別在庫」テーブルでぶつかる場合です。表2によると、出庫指示は「出庫指示」を主キー(出庫番号、 棚番号、 商品コード)の順に読み、その順に「棚別在庫」(主キーは棚番号、 商品コード)を更新します。ジョブが違っても、1回のコミットの中では常に棚番号→商品コードの昇順、つまり「棚別在庫」の主キー順に更新します。ロックの取得順が全ジョブで一致するため、循環待ちは起きません。公式解答例では「“棚別在庫”を常に主キーの順で更新しているから」という趣旨です。

設問2(1)(c)

ケース3は、在庫引当ジョブと出庫指示ジョブが、進み具合によって同時に動く場合です。どちらも「注文明細」の注文状態を更新します。ただしジョブは注文番号の範囲で分割されているので、異なるジョブが同じ注文の明細行を更新することはありません。ロックの競合自体が起きないため、デッドロックのリスクはありません。公式解答例では「異なるジョブが同じ注文の明細行を更新することはないから」という趣旨です。採点講評では(1)cの正答率が低く、注文番号の範囲で分割している点に着目すること、マスター・在庫系のテーブルとトランザクション系のテーブルではロック競合のリスクが違うことを理解するよう求めています。

設問2(2)

ケース1の原因は、ジョブによって「在庫」を更新する順序が違うことです。対策は、コミット単位とISOLATIONレベルを変えずに、更新順序を商品コード順にそろえることです。公式解答例では次の二通りの選び方が示されています。注文登録処理を選ぶ場合は、「“注文明細”に行を商品コードの順に登録する」または「商品コードの順に注文明細番号を付与する」。こうすると、在庫引当が主キー順に読むだけで商品コード順の更新になります。在庫引当処理を選ぶ場合は、「“在庫”の行を商品コードの順に更新する」。答案では処理名と変更内容を対応させ、「商品コード順」という具体的な順序を30字以内で明記します。

設問3(1)(あ)

空欄xはLAG関数のPARTITION BYに当たり、区画の切り方で「1行前の出庫時刻」が何を指すかが変わります。A.ピッカーIDで区画を切ると、同じピッカーの出庫時刻が一日を通して並びます。すると、ある注文の1番目の商品の1行前は、そのピッカーが直前の注文で最後に出庫した時刻になります(COALESCEで出庫開始時刻を使うのは、その日の最初の1行だけです)。棚の前での待ち時間は含まれますが、直前の注文の梱包と出荷担当者への受渡しの時間まで入ってしまいます。公式解答例では、あは「A.ピッカーID」です。

設問3(1)(い)

B.棚番号で区画を切ると、同じ棚で誰かが直前に出庫した時刻との差になります。これはその棚が使われた間隔にすぎず、ピッカーが棚の前で待った時間は表しません。そのため、長い待ちの実証という分析目的を達成できません。公式解答例では、いは「B.棚番号」です。本文の定義(1番目の商品は出庫開始時刻から、2番目以降は一つ前の商品の出庫時刻から)に合うのは、残りのB.出庫番号で区画を切る場合です。採点講評では、あ・いの正答率が低く、区画ごとにどんな並びの出庫時刻が得られるかを考えれば正答できるとしています。

設問3(1)(う)

下線部の対策は、順路の方向を変えずに、多くのピッカーが棚3番に集中しないよう出庫指示を作るものです。本文の例では、あるピッカーの順序が「棚3番S3→棚6番S6」です。デッドロックが起きるのは、別のピッカーが同じ2行を逆の順序で扱う場合です。つまり1番目に棚6番を回らせる指示で、公式解答例では、うは「6番」です。

設問3(1)(え)

1番目の棚6番で出庫する商品は、例の1人目の2番目と同じS6です。図2で棚6番にはS4とS6がありますが、1人目と同じ「棚別在庫」の行(6番、 S6)を扱う必要があります。公式解答例では、えは「S6」です。

設問3(1)(お)

2番目は、1人目の1番目と同じ棚3番です。こうすると、1人目は(3番、 S3)→(6番、 S6)、2人目は(6番、 S6)→(3番、 S3)の順に「棚別在庫」の行を更新することになり、ロックの順序が逆転します。公式解答例では、おは「3番」です。

設問3(1)(か)

2番目に棚3番で出庫する商品はS3です。これで二つの出庫指示ジョブが「棚別在庫」の同じ2行を逆の順序でロックする組み合わせになり、表3のケース2でデッドロックが起き得ます。公式解答例では、かは「S3」です。

設問3(2)

下線の対策を適用すると、ピッカーごとの出庫の順序と「棚別在庫」を更新する順序が、ジョブによってそろわなくなり得ます。設問3(1)のように更新の順序が逆転すると、ケース2の「常に同じ順序で更新しているのでリスクがない」という前提が崩れます。回避策は、コミット単位とISOLATIONレベルを変えずに、「棚別在庫」を更新する順序を全ジョブ共通の固定した順序にすることです。公式解答例では、「“出庫指示”の読込み順を出庫番号、商品コード、棚番号の順に変更する」または「“棚別在庫”の行を商品コード、棚番号の順に更新する」という趣旨が示されています。答案では、どのテーブルをどの列の順に読む(更新する)かを40字以内で具体的に書きます。

学習のポイント

主キー順の挿入と空き領域の関係、ロック順序によるデッドロックの成否の判断、ウィンドウ関数の区画の選び方を、本文の仕様から根拠を示して説明できるようにします。

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

関連する過去問一覧

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