DB勉強会レポート_2019年01月29日(火) & 02月05日(火)実施分

こんにちは。
今回からは午後Ⅱに突入します。
流石に難易度は高いですが、出来るだけ分かりやすくお伝え出来ればと思います(私の頭で分かる説明が書ければ、世の中の多くの人は理解できるはず)。

【お願い】午後Ⅱは問題文が非常に多く、引用するとそれだけで文章量が膨れてしまうので、本記事を読まれる際は手元に問題用紙をご用意下さい。

解説範囲

平成30年度 春期 データベーススペシャリスト試験 午後Ⅱ 問1 設問1

解説の前に

解説に入る前に、午後Ⅱの概要を確認しておきましょう。

項目 内容
試験時間 14:30~16:30 (120分)
出題形式 記述式
出題数 / 解答数 出題数:2問 / 解答数:1問

問題文が非常に長く、じっくりと詳細を気にして読み進めていては時間内に終わりません。
また、業務フローやシステムの情報が満載でとても一読で頭に入るものではありません。
よって、以下のような読み方を意識する必要があります。

  • 大項目、中項目、小項目を意識しながら全体の構成を掴む(スキミング)
  • 必要な情報や重要な数字を、大項目と中項目程度に絞ってさっと拾い読みする(スキャニング)

また、設問数が多くないため、一問当たりの配点が大きいのも特徴です。
解答に必要な根拠が問題文のどこに書かれているかを明らかにする必要があります。

以上を踏まえて、解説に入っていきましょう。

設問1 (1)

図1中の, に入れる一つ又は複数の列名を答えよ。なお, 列名には本文又は図表中の用語を用いること。また, , に入れる列が主キーを構成する場合, 主キーを表す実線を下線を付けること。


図1 経費精算システムのテーブル構造(未完成・一部省略)より、空欄が含まれるテーブル情報を確認しましょう。

仮払金申請(申請番号, 社員番号, 申請理由, 仮払金申請状態, 処理年月,
仮払金精算(


仮払金とは何ぞや?な方は、まずこちらをご覧下さい。

まず、仮払金申請について問題文中から必要な情報を拾っていきます。

  • p.7の「2. 手続の種類(3)仮払金精算 ②」より、申請には社員番号申請理由仮払金額精算期限が必要になる。
  • p.7の「2. 手続の種類(3)仮払金精算 ③」より、未精算の仮払金を仮払金残高として記録する。
  • p.7の「3. 申請・生産の流れ(1)申請 ①」より、申請には一意な申請番号が付与される。
  • p.7の「3. 申請・生産の流れ(2)上司承認, 庶務精査, 経費管理責任者確認 ①」より、申請が承認された場合は上司承認日が記録される。
  • pp.7 – 8の「3. 申請・生産の流れ(2)上司承認, 庶務精査, 経費管理責任者確認 ②」より、精査の結果問題なければ精査日が記録され、その後申請によって回付先が分岐する。
  • 旅費交通費、一般経費 -> 経費管理責任者
  • 仮払金 -> 事務センタ
  • p.8の「3. 申請・生産の流れ(3)支払 ③」より、仮払金は申請を基に一定額の支払いを行い、申請に支払実行日を記録する。

仮払金申請テーブルにすでに存在している列を除くと、に入る仮払金額精算期限仮払金残高上司承認日精査日支払実行日を抽出出来ます。

この問題を解いたとき、責任者承認日を解答に入れてしまいました。
よく読めば分かりますが、この列は旅費交通費と一般経費の精算時のみに記録されるものです。

「3. 申請・生産の流れ(1)申請 ②」の説明より証憑番号も列に入れるべきだと思いましたが違いましたね。
「3. 申請・生産の流れ(1)申請 ①」の説明を読んでみて下さい。

仮払金を使用して旅費, 一般経費の支払いを行なった場合, 旅費交通費生産又は一般経費精算を行う必要がある。


仮払金を使用して旅費や一般経費の支払いを行う場合、その時点ではまだ領収書などの証憑は持ち合わせていません。
支払いを終え、証憑を入手してから旅費交通費生産又は一般経費精算を行うフローですね。

よって、上記の責任者承認日証憑番号仮払金申請テーブルの列には入りません


次に、仮払金精算テーブルの列名を探していきます。

  • p.7の「2. 手続の種類(3)仮払金精算 ④」より、一つの仮払いに対する精算が複数日に分かれることがある。
  • 仮払金申請仮払金精算1:nの関係にある。
  • 仮払金申請テーブルの行を一意に参照するため申請番号が主キーになる。
  • 同じくp.7の「2. 手続の種類(3)仮払金精算 ④」より、精算日に対応した精算金額を記録するため。精算日も主キーになる。また、記録される精算金額も列に入る。

よって、仮払金精算テーブルのには申請番号」、「精算日」、「精算金額が入ります。


ここで、仮払金残高仮払金精算テーブルに入ってもいいのではないかと疑問が残りませんか?

精算するごとに仮払金残高を更新していけば良いように思えます。
しかし、p.11の「表3 主な処理の CRUD」の仮払金精算テーブルを見て下さい。
可能なCRUD処理はC:追加のみです。
つまり、仮払金精算テーブルは追加は出来ても更新は出来ません。

なので、精算ごとに更新は必要になる仮払金残高は列として不適切ということになります。

設問1 (2)

表6中の太枠内に適切な字句を記入して, 太枠内を完成させよ。

「表6 “一般経費申請”テーブルのテーブル定義表(未完成)」はp.14にあります。

データ行NOT NULL格納長(バイト)索引の種類と構成列の項目に対して、外貨金額支払先支払い目的支払予定日支払番号列が空欄になっています。
問題文から情報を探して埋めていきましょう。

参照する情報は、p.10の「表1 主な列とその意味・制約」、p.12の「RDBMSの仕様」、「表5 使用可能なデータ」、p.13の「テーブルの物理設計」です。

それらを基に関連する情報を整理すると以下の表の通りになります。

列名 表1 RDBMSの仕様 表5 テーブルの物理設計
外貨金額 【値の範囲】
0.01 ~ 9,999,999,999.99

【申請登録時の指定】
任意

NOT NULL制約なし
=> + 1バイト
【データ型】
DECIMAL(m,n)
m = 精度
n = 位取り

【格納領域】
“m÷2+1″の小数部切捨て

【NOT NULL】
N
支払先 【値の範囲】
全角文字:100文字以内
平均文字数:20文字

【申請登録時の指定】
経費支払依頼:必須
立替経費精算:任意

NOT NULLをかけると立替経費精算申請登録時の指定も「必須」になってしまうので、検査制約をかけるため、NOT NULL制約なし
=> + 1バイト
【データ型】
NCHAR VARYING(n)

【格納領域】
“値の文字数 × 2″バイト + 4バイト

【NOT NULL】
N

【格納長】
平均文字数が20文字なので、20バイトを基準に算出する

支払目的 【値の範囲】
全角文字:1,000文字以内
平均文字数:64文字

【申請登録時の指定】
必須

NOT NULL制約あり 【データ型】
NCHAR VARYING(n)

【格納領域】
“値の文字数 × 2″バイト + 4バイト

【NOT NULL】
Y

【格納長】
平均文字数が64文字なので、64バイトを基準に算出する

支払予定日 一般経費申請の支払完了時に支払伝票の支払い予定日を記録
=> 申請登録時の指定は任意
NOT NULL制約なし
=> + 1バイト
【データ型】
DATE

【格納領域】
4バイト

【NOT NULL】
N
支払番号 一般経費申請の支払完了時に支払伝票の支払番号(1 ~ 99,999)を記録
=> 申請登録時の指定は任意
NOT NULL制約なし
=> + 1バイト
【データ型】
INTEGER

【格納領域】
4バイト

【NOT NULL】
N

外貨金額m精度で、固定小数点数における小数点以上の桁数を、n位取り小数点以下の桁数をそれぞれ表しています。

9,999,999,999.99の小数点以上の桁数の「12」がmに入り、小数点以下の桁数の「2」がnに入ります。

よって、外貨金額の格納長は「12 ÷ 2 + 1 + 1」より「8バイト」となります。


上記までの情報を基に表6の空欄を埋めると、以下の通りになります。

列名 \ 項目 データ型 NOT NULL 格納長(バイト)
外貨金額 DECIMAL(m,n) N 12 ÷ 2 + 1 + 1 = 8バイト
支払先 NCHAR VARYING(n) N 20 × 2 + 1 + 4 = 45バイト
支払い目的 NCHAR VARYING(n) N 64 × 2 + 4 = 132バイト
支払予定日 DATE N 4 + 1 = 5バイト
支払番号 INTEGER N 4 + 1 = 5バイト

索引の種類と構成列に関して、「p.13の(4)」を確認すると必要な情報が載っています。

p.9の「図1 経費精算システムのテーブル構造(未完成・一部省略)」の一般経費申請テーブルより、申請番号が主キーで表6のP欄に「1」がついており、社員番号内訳科目コード通過コードは外部キーで表6のNU欄にそれぞれ「1」がついています。

支払伝票テーブルの複合主キーとなっていてなおかつ一般経費申請テーブル内で値が一意の組み合わせになる支払予定日支払番号の列は、U欄にそれぞれ「1」、「2」が入ります。

設問1 (3)

表6中のに入れる適切な字句を答えよ。ここで, 1 ~ 999のような, 値の上限・下限に関する制約は, 検査制約では定義しないものとする。

に入る検査制約を満たすCHECK文の空所補充問題です。
そもそも検査制約とは何か、忘れてしまってることもあるでしょうから、今一度おさらいしておきましょう。

リレーショナルデータベースでテーブルにデータを追加・更新する際の制約の一つで、指定した条件を満たしたデータしか記録できないようにするもの。テーブル作成時などに各列に対して設定することができ、条件式などを用いてデータが満たすべき条件を記述する。例えば「価格」フィールドに対して「価格>0」というCHECK制約を設定しておけば、価格として負の値を記録しようとしてもDBMSが制約違反として拒否する。

CHECK制約【 チェック制約 】検査制約: IT用語辞典より抜粋


表1の中で、制約をかけないと挿入・更新時にDBの整合性が失われる列はどれでしょうか。
支払先です。

設問1 (2)支払先のRDBMSの仕様でも説明した通り、NOT NULLをかけると立替経費精算申請登録時の指定も「必須」になってしまうので、検査制約によって挿入・更新するデータを制限しなければなりません。

この検査制約でやりたいことは、

  • 申請種別が「経費支払依頼」の場合、値がNULLの時にデータの挿入を拒否する
  • 申請種別が「立替経費申請」の場合、値がNULLであってもデータの挿入を許可する

ことです。

表1の「申請種別」列を読むと、’1’が「立替経費申請」、’2’が「経費支払依頼」です。


以上をCHECK文で表現すると、

CHECK(申請種別 = '1' OR 申請種別 = '2' AND IS NOT NULL)

となり、返り値がTRUEの場合はデータの挿入・更新が出来、FALSEの時は出来なくなります。

よって、には「申請種別 = '1' OR 申請種別 = '2' AND IS NOT NULL」が入ります。

設問1 (4)

表7中のa ~ dに入れる適切な数値を答えよ。ここで, 空き領域率は10%とする。


aに入る「ページサイズ」の値は、「表2 主なテーブルの見積もり行数・データ所要量」の「ページサイズ(バイト)」を見ると、「4,000」だと分かります。

「ページサイズ」を「平均行長」で除算すれば「1データページ当たりの平均行数」を求めることが出来ますが、ここで注意しなければならないのは、設問文の「空き領域率は10%とする」です。
つまり、使用率の「100 – 10 = 90%」を考慮に入れなければならないので、算出基準となるページサイズは「4,000 × 0.9 = 3,600」となります。

よって、1データページ当たりの平均行数は「3,600 ÷ 239 ≒ 15行」となり、bには「15」が入ります。


cの「必要データページ数」は、「見積もり行数」を「1データページ当たりの平均行数」で除算すれば求められます。

よって、cには「1,500,000 ≒ 15」より、「100,000」が入ります。


最後にdですが、「必要データページ数」に「ページサイズ」を乗算すれば求められます。
注意すべきは単位の「百万バイト」なので、算出した数字を「1,000,000」で除算することを忘れないで下さい。

「100,000 × 4,000 ÷ 1,000,000」より、dには「400」が入ります。

今回の設問の解答

  • 設問1
  • (1)
    • ア. 精算期限, 上司承認日, 精査日, 仮払金額, 仮払金残高, 支払実行日
    • イ. 申請番号精算日精算金額
  • (2)
  • (3) ウ. 申請種別 = '1' OR 申請種別 = '2' AND 支払先 IS NOT NULL
  • (4)
    • a. 4,000
    • b. 15
    • c. 100,000
    • d. 400

参考ページ

次回解説予定範囲

平成30年度 春期 データベーススペシャリスト試験 午後Ⅱ 問1 設問2 – 設問3 (1)

関連記事

DB勉強会レポート_2019年02月13日(水)実施分

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ

BPSアドベントカレンダー