データベーススペシャリスト　令和4年 午後1　解説解答

- 問1
  - [設問1-(1)](#問1-設問1-1)
  - [設問1-(2)](#問1-設問1-2)
  - [設問2-(1)](#問1-設問2-1)
  - [設問2-(2)](#問1-設問2-2)
- 問2
  - [設問1-(1)](#問2-設問1-1)
  - [設問1-(2)](#問2-設問1-2)
  - [設問1-(3)](#問2-設問1-3)
  - [設問1-(4)](#問2-設問1-4)
  - [設問1-(5)](#問2-設問1-5)
  - [設問2-(1)](#問2-設問2-1)
  - [設問2-(2)](#問2-設問2-2)
  - [設問2-(3)](#問2-設問2-3)
- 問3
  - [設問1-(1)](#問3-設問1-1)
  - [設問1-(2)](#問3-設問1-2)
  - [設問2-(1)](#問3-設問2-1)
  - [設問2-(2)](#問3-設問2-2)
  - [設問3-(1)](#問3-設問3-1)
  - [設問3-(2)](#問3-設問3-2)

公式サイトの問題冊子はこちら。
https://www.ipa.go.jp/shiken/mondai-kaiotu/gmcbt80000008smf-att/2022r04a_db_pm1_qs.pdf

# 問1-設問1-(1)
*図1中の欠落しているリレーションシップを補って図を完成させよ。*
- 「問合せの媒体は、Web上の問合せフォームか電話による通話である」なので、「Web問合せ」「通話」は「問合せ」のサブタイプと読み取れる
- (2)を完成させた後の外部キーを、図1のリレーションシップにすべて反映させる
::: note info
- 「**Web問合せ**」「**通話**」は共に**問合せのサブタイプ**
- 「**発信通話**」は**通話のサブタイプ** 
```mermaid
graph TB
 案件-->|案件番号| 問合せ
 CC要員-->|CC要員社員番号| 通話
 Web問合せ-->|Web問合せ番号|発信通話
 SLP-->|SLPBPコード| SLPweb問合せ
```
:::
# 問1-設問1-(2)
*図2中のア～カに入れる一つ又は複数の適切な属性名を補って関係スキーマを完成させよ。*
## ア
- 「問合せの媒体は、Web上の問合せフォームか電話による通話である。いずれであるか**媒体区分**で分類する」
- 「一つの問合せは(中略)問合せ番号で識別し、**問合せ年月日時刻**、**問合せ内容**のほかに(中略)**お名前**と**電話番号**を記録する」
- 「(1)問合せに対して(中略)**案件番号**を発番して案件を登録する。」
- **案件番号**は案件テーブルへの外部キーに該当する
::: note info
媒体区分、問合せ年月日時刻、問合せ内容、お名前、電話番号、案件番号(FK)
:::
## イ
- サブタイプに「SLPweb問合せ」をもつので、それを識別するための属性が必要
::: note info
SLPweb問合せフラグ
:::
## ウ
- 「そのWeb問合せがSLP経由だった場合(中略)Web問合せに経由した**SLPのBPコード**を記録している」
- 「**SLPのBPコード**」はSLPテーブルへの外部キーに該当する
::: note info
SLPのBPコード(FK)
:::
## エ
- 「通話の成立は**通話成立フラグ**で分類する」
- 「通話の場合、**通話したCC要員の社員番号**、**通話時間**、受信か発信かの**受発区分**、音声データである**通話音声**を記録している」
- 「**通話したCC要員の社員番号**」はCC要員テーブルへの外部キー
::: note info
通話成立フラグ、通話社員番号(FK)、通話時間、受発区分、通話音声
:::
## オ
- 「入ったWeb問合せに対してCC要員が製品使用者に電話をかける」とあるので、Web問合せテーブルへの外部キーが必要
::: note info
Web問合せ番号(FK)
:::
## カ
- 「出張手配は(中略)**出張年月日**と**出張時間帯**を決める」
::: note info
出張年月日、出張時間帯
:::
# 問1-設問2-(1)
*図3中のあ～うには、図1に示した現状の概念データモデル中のエンティティタイプのいずれかが入る。あ～うに入れる適切なエンティティタイプ名を答えよ。*
## あ
- 「製品シリーズごとに、用いているユニットを登録する」とあるので、「製品シリーズ」と「ユニット」の間にはリレーションシップか中間テーブルが存在すると読み取れる
- すでに何かのテーブルと「ユニット」の間に中間テーブルが描かれているが、その何かのテーブルのところに「製品シリーズ」を当てはめることができる
::: note info
製品シリーズ
:::
## い
- 「要点検修理FAQには、対象のユニットが何か設定するとともに、対応する点検修理項目を関連付けておく」とあるので、「要点検修理FAQ」と「点検修理項目」の間にはリレーションシップか中間テーブルが存在すると読み取れる
- すでに何かのテーブルと「要点検修理FAQ」の間に中間テーブルが描かれているが、その何かのテーブルのところに「点検修理項目」を当てはめることができる
::: note info
点検修理項目
:::
## う
- 「案件でEUへの回答に適用したFAQは、案件適用FAQとして案件に関連付け、・・・」とあるので「案件」と「FAQ」の間にはリレーションシップか中間テーブルが存在すると読み取れる
- すでに何かのテーブルと「FAQ」の間に中間テーブルが描かれているが、その何かのテーブルのところに「案件」を当てはめることができる
::: note info
案件
:::
## (b)
*図3中の欠落しているリレーションシップを補え。*
- (2)を完成させた後の外部キーを、図3のリレーションシップにすべて反映させる
::: note info
```mermaid
graph TB
 ユニット-->|ユニットコード| 要点検修理FAQ
 FAQ-->|FAQ番号| c
 FAQ-->|FAQ番号| e
 FAQ-->|関連FAQ番号| e
 要管理機能部品-->|機能管理番号| b
```
:::
# 問1-設問2-(2)
*図4中のキ～シに入れる一つ又は複数の適切な属性名を補って関係スキーマを完成させよ。*
## キ
- 設問2(1)より、空欄「あ」に「製品シリーズ」が入る
- 「製品シリーズごとに、用いているユニットを登録する」とある
- 「製品シリーズ」「ユニット」それぞれとの間に多:1のリレーションシップが設定されているので、テーブルaは多:多の「製品シリーズ」と「ユニット」を繋ぐ中間テーブルだと読み取れる
- 多:多で繋ぐテーブルそれぞれの主キー「製品シリーズコード」「ユニットコード」を組み合わせた複合キーを中間テーブルに設定することで多:多を表現できる
::: note info
製品シリーズコード(PK)、ユニットコード(PK)
:::
## ク
- 「機能部品に起因する故障の頻発を予見した場合、その機能部品を要管理機能部品として要管理内容を登録し、組み込んでいる**ユニットと関連付ける**。」
- 「要管理機能部品」「ユニット」それぞれとの間に多:1のリレーションシップが設定されているので、テーブルbは多:多の「要管理機能部品」と「ユニット」を繋ぐ中間テーブルだと読み取れる
- 多:多で繋ぐテーブルそれぞれの主キー「機能部品番号」「ユニットコード」を組み合わせた複合キーを中間テーブルに設定することで多:多を表現できる
::: note info
- 機能部品番号(PK)、ユニットコード(PK)
:::
## ケ
- 「FAQ中に存在するキーワード(以下、KWという)をあらかじめ登録し、FAQとその中で用いられるKWを関連付ける。」
- 同じ「KW」を異なる「FAQ」に紐付けるケースが想定される
- 同じ「FAQ」を異なる「KW」に紐付けるケースが想定される
- 「KW」との間に多:1のリレーションシップが設定されているので、テーブルcは多:多の「FAQ」と「KW」を繋ぐ中間テーブルだと読み取れる
- 多:多で繋ぐテーブルそれぞれの主キー「KW」「FAQ番号」を組み合わせた複合キーを中間テーブルに設定する
::: note info
KW(PK)、FAQ番号(PK)
:::
## コ
- 「案件でEUへの回答に適用した**FAQ**は、案件適用FAQとして**案件**に関連付け、可能性の高いFAQの順に**可能性順位**を記録する」
- 多:多で繋ぐテーブルそれぞれの主キー「案件番号」「FAQ番号」を組み合わせた複合キーを中間テーブルに設定する
::: note info
案件番号(PK)、FAQ番号(PK)、可能性順位
::: 
## サ
- 「FAQには、問合せ内容の解釈によって類似のFAQが複数存在し得るので、類似するFAQを関連FAQとして関連付け、関連度合いをA～Cの3段階に分けて**関連度ランク**として設定する」
- 「サ」は「FAQ」と「関連するFAQ」を多:多で関連付けるための中間テーブルと考えられるので、ここに双方の主キー「FAQ番号」を組み合わせた複合キーを設定する
::: note info
FAQ番号(PK)、関連FAQ番号(PK)、関連度ランク
:::
## シ
- 「要点検修理FAQには、対象のユニットが何か設定するとともに、対応する点検修理項目を関連付けておく」
- 「要点検修理FAQ」「点検修理項目」それぞれとの間に多:1のリレーションシップが設定されているので、テーブルbは多:多の「要点検修理FAQ」と「点検修理項目」を繋ぐ中間テーブルだと読み取れる
- 前者の主キーは「FAQ番号」、後者の主キーは「MTコード」
::: note info
FAQ番号(PK)、MTコード(PK)
:::
# 問2-設問1-(1)
*図2中のa、bに入れる適切な字句を答えよ。*
## a
- 見積回答明細 Aと商品 Cとの間には、商品コードを介したリレーションシップが存在する
::: note info
商品コード
:::
## b
- 「モデル名又は定価のいずれかが変更」は「モデル名が変更 OR 定価が変更」と同義
::: note info
OR
:::
# 問2-設問1-(2)
*“商品”テーブルの設計変更について、表1中の案1を採用した場合、他のどのテーブルの、どの制約を変更する必要があるか。テーブル名と制約を全て答えよ。*
- 「見積依頼明細」「見積回答明細」は{商品コード}を外部キーにもつ
- 案1を採用すると「商品」の主キーは{商品コード}から{商品コード、適用開始日}に変更され、「商品」は{商品コード}を一意とするテーブルではなくなる
::: note info
- テーブル名：見積依頼明細、見積回答明細
- 制約：外部キー制約
:::
# 問2-設問1-(3)
*表2中のc～hに入れる適切な字句を答えよ*
## c、d
- 「同一の適用開始日に同一の商品を複数回更新することはない」とあるので、　主キーを{商品コード、適用開始日}とすることで複数回の変更に対応できる
::: note info
商品コード、適用開始日
:::
## e、f
- CREATE TRIGGER トリガー名 [e/f] UPDATE ON ～　の構文なので、[e/f]にはBEFORE かAFTERが入る
- トリガー1では「適用開始日がNULLの場合、現在日付に更新」を実施
- トリガー2では「対象行の更新前の行を“商品履歴”テーブルに挿入」「挿入行の適用終了日には、更新後の行の適用開始日の前日を設定」を実施
- 商品履歴テーブルの主キーは{商品コード、適用開始日}なので、トリガー2発動前に適用開始日を非NULLにしておかなければ制約違反になる
::: note info
e : BEFORE
f : AFTER 
:::
## g
- トリガー2のVALUE関数なので、空欄には「OLD2」か「NEW2」のどちらかが入る
- 「g.適用開始日」が商品履歴(適用開始日)に設定される
- 適用開始日は「対象行の**更新前の**行を商品履歴テーブルに挿入する」
::: note info
OLD2
:::
## h
- トリガー2のVALUE関数なので、空欄には「OLD2」か「NEW2」のどちらかが入る
- 「ADD_DAYS(h.適用開始日, -1)」が商品履歴(適用終了日)に設定される
- 適用開始日は「挿入行の適用終了日には、**更新後の**行の適用開始日の前日を設定する」
::: note info
NEW2
:::
# 問2-設問1-(4)
*表5中のi～kに入れる適切な字句を答えよ*
## i
- 先にjを解いておく
- 「ADD_DAYS(LEAD(Q2.見積回答日) OVER (PARTITION BY Q2.商品コード ORDER BY Q2.見積回答日), -1) AS 適用終了日」なので、次行の見積回答日-1が入る
::: note info
2022-08-31
:::
## j
- 「Q2.見積回答日 AS 適用開始日」なので、見積回答日が入る
::: note info
2022-09-01
:::
## k
- 「注記1 ADD_DAYS(引数1,引数2)は(中略)引数1がNULLの場合はNULLを返す」
- 「注記4 LEAD関数は(中略)1行後の行がない場合はNULLを返す」
- kの行は「1行後の行がない場合」なのでNULLを返す
::: note info
NULL
:::
# 問2-設問1-(5)
*表5のうち、”商品“テーブルへの更新行、“商品履歴”テーブルへの挿入行に当たる行を、それぞれ行番号で全て答えよ*
- 商品コードを更新する際、更新前情報を商品履歴に挿入する
- 「商品テーブルへの更新行」は、各商品コードの中で適用開始日が一番新しいもの
- 「商品履歴テーブルへの挿入行」は、各商品コードの中で適用開始日が一番新しいものを除く全て
::: note info
商品テーブルへの更新行:3,5,6
商品履歴テーブルへの挿入行:1,2,4
:::
# 問2-設問2-(1)
*本文中のア～オに入れる適切な字句又は数値を答えよ*
## ア
- RPO(復旧ポイント目標)は障害復旧時に遡ることができる時間の長さに相当する
- 「バックアップは、**データベースを停止して**、オフラインで取得する」ので、フルバックアップ中にデータベースは更新されない
- 「**フルバックアップとアーカイブログ**を使って、データベースを回復することができる」とあるので、アーカイブログになる前のログは回復対象外
::: note info
ログの量
:::
## イ
- 「データベースのフルバックアップは1日に1回取得し、**ログの切換えは5分に1回**行い、回復時にはオブジェクトストレージに保存したフルバックアップとアーカイブログを使って回復する」
::: note info
5分
:::
## ウ
- リストア時間=180[Gバイト]÷100[Mバイト/秒]×1000[Gバイト/Mバイト]
::: note info
1800
:::
## エ
- 24時間分のログのページ数=10[ページ/秒]×60[秒/分]×60[分/時]×24[時間]
::: note info
864000
:::
## オ
- ログ適用時間=864000[ページ]×2[ミリ秒/ページ]÷1000[ミリ秒]
::: note info
1728
:::
# 問2-設問2-(2)
*”2.参照専用インスタンス“について、参照専用インスタンスへのレプリケーションを非同期型にすると、見積システムへの影響を最小化できるのはなぜか。レプリケーションの仕様に基づいて、30字以内で答えよ*
- 「非同期型では、**複製先へのログの到達を待たずに**、複製元のトランザクションがコミットされる」
::: note info
非同期型では、複製先へのログの到達を待たないから
:::
# 問2-設問2-(3)
*“3.参照専用インスタンスへのフェイルオーバーによる業務継続”について、参照専用インスタンスでは、本番インスタンスでコミット済みの変更が失われる可能性がある。どのような場合か。レプリケーションの仕様に基づいて、30字以内で答えよ。*
- 「非同期型では、複製先へのログの到達を待たずに、複製元のトランザクションがコミットされる」ので、コミット済みの変更が複製先に反映されていない場合がある
::: note info
複製元の変更が、複製先に反映されていない場合
:::
# 問3-設問1-(1)
*注文登録処理が”注文明細“テーブルに行を挿入するとき、再編成で予約した空き領域が使われないのはなぜか。行の挿入順に着目し、理由をRDBMSの仕様に基づいて、40字以内で答えよ。*
- 「注文番号は単調増加」なので、新しい注文番号は最大値をもつ
- 「この1年ほど行の削除は行われず」なので、「挿入行のキー値に近い行が格納されているページ」の前後付近には削除による空き領域は生じない
- 「再編成も行っていない」ので、「各ページ中に空き領域を予約」も行われない
- 従って、定められた仕様の下では、最終レコードの後ろにしか新しい登録に必要な領域を確保できない
::: note info
注文番号は単調増加なので、古い注文番号の近くに行を挿入しないから
::: 
# 問3-設問1-(2)
*行の削除を行わず、直ちに再編成だけを行うと、ストレージが満杯になるリスクがあるのはなぜか。前回の再編成の時期及び空き領域の割合に着目し、理由をRDBMSの仕様に基づいて、40字以内で答えよ。*
- 再編成前の状態だと、最終レコードまで空き領域はほとんど無かったが、再編成すると、指定された空き容量が各ページに挿入される
- 挿入された空き容量の分だけ新しいページが必要になる
- ページが増えた分だけストレージの空きが減る
::: note info
再編成後に追加した各ページで既定の空き領域分のページが増えるから
:::
# 問3-設問2-(1)
*表3中のa～cに入れる適切な理由を、それぞれ30字以内で答えよ。ここで、在庫は適正に管理され、欠品は無いものとする。*
## a
- 在庫と注文明細は1:多の関係なので、在庫引当バッチによって、在庫テーブル内の各レコードにアクセスする順序は異なる場合がある
ということは
0. 在庫引当バッチ1が在庫1に占有ロック
0. 在庫引当バッチ2が在庫2に占有ロック
0. 在庫引当バッチ1が在庫引当バッチ2による在庫2占有ロック解除待ち
0. 在庫引当バッチ2が在庫引当バッチ1による在庫1占有ロック解除待ち
でデッドロックが発生、という挙動があり得る。
::: note info
異なる商品の“在庫”を逆順で更新することがあり得るから
:::
## b
- 出庫指示バッチは同一出庫番号の単位で実行され
0. 出庫番号は{棚番号,商品コード}の順にアクセス
0. 棚別在庫は{棚番号,商品コード}の順にアクセス
- 棚別在庫テーブル内の各レコードへのアクセスが逆順になることが無い
- 競合するレコードに対して先にロックをかければその先は競合相手の影響を受けることなくコミットまで進むことができる
::: note info
“棚別在庫”を常に主キーの順で更新しているから
:::
## c
- 在庫引当バッチは「注文状態が未引当の注文明細」が対象
- 出庫指示バッチは「注文状態が引当済の注文明細」が対象
- この場合は、アクセス対象のレコードが競合しない
::: note info
異なるジョブが同じ注文の明細行を更新することはないから
:::
# 問3-設問2-(2)
*表3中のケース1のリスクを回避するために、注文登録処理又は在庫引当処理のいずれかのプログラムを変更したい。どちらかの処理を選び、選んだ処理の処理名を答え、プログラムの変更内容を具体的に30字以内で答えよ。ただし、コミット単位とISOLATIONレベルを変更しないこと*
- 注文明細テーブルの並びと在庫テーブルの並びは連動しないので、異なる注文明細同士だと、在庫テーブルの順序はバラバラになる
- 在庫テーブルに逆順でアクセスするトランザクションと競合した場合にデッドロックが発生することがある
- 注文明細テーブルと在庫テーブルの並びが同じならデッドロックしない
::: note info
注文登録
商品コードの順に注文明細番号を採番する
:::
# 問3-設問3-(1)
*本文中のあ～かに入れる適切な字句を答えよ*
## あ、い
- B.出庫番号の場合 : 出庫開始から出荷担当に受け渡す直前の出庫までの出庫間隔時間を把握することができる
- A.ピッカーIDの場合 : 同じピッカーが複数の出庫に対応すると、後の出庫の最初の出庫間隔時間は前の出庫の最後の商品の出庫時刻から後の出庫の最初の商品の出庫までの間になる。ここには、出荷担当への受け渡し時間が加算されている
- B.棚番号の場合 : 異なるピッカーが記録した出庫時間同士の引き算になるため、ピッカーの待ち時間は反映されない
::: note info
- あ : A.ピッカーID 
- い : B.棚番号
:::
## う
- 逆順のロックが並行したときにデッドロックが起こる
- 表2の出庫指示「ピッカーの順路が1方向となる出庫指示」、図2の黒矢印で示した出庫作業の順路より、棚400のあとに棚1～に戻る順序が許される
- そのルールのもとでは出庫指示が{棚番号、商品コード}={6,S6},{3,S3}の順に並ぶ場合がある。
- その順で棚別在庫を更新すると、{棚番号、商品コード}が{3,S3},{6,S6}になるバッチとの間でデッドロックが生じてしまう
::: note info
- う : 6
- え : S6 
- お : 3
- か : S3 
:::
# 問3-設問3-(2)
- 棚別在庫の更新順を{棚番号、商品コード}か{商品コード、棚番号}のどちらかに統一することでデッドロックを回避できるが、前者の場合、「ピッカーが同じ棚に集中しないように出庫指示を作成する対策」がとれない 
- 商品S3は棚番号202からも出庫できるので、一方のバッチを{商品コード、棚番号}={S3,3},{S6,6}の順、もう一方を{商品コード、棚番号}={S3,202},{S6,6}の順とすることでピッカーの集中を緩和することもできる 
::: note info 
- 棚別在庫の更新を{商品コード、棚番号}の順で行う
:::