基本情報技術者 2014年 秋期 午後 問04
書籍を管理する関係データベースの設計及び運用に関する次の記述を読んで、設問1~4に答えよ。
ある会社の資料室では、社員(以下、利用者という)と窓口担当者の利便性を向上する目的で、所蔵する書籍を管理するデータベースを再構築することにした。この会社の資料室では、業務に関連する書籍を管理しており、利用者への貸出しも実施している。
従来のデータベースは、図1に示すとおり、所蔵する書籍と現在の貸出状況を管理する書籍表で構成されている。下線付きの項目は、主キーを表す。
↩設問1
〔書籍表に関する説明〕
(1) 利用者に貸出中の書籍には、貸出日と返却予定日が格納されている。これらの項目がnullの書籍は、貸し出されていないことを表す。
(2) 社員番号には、その書籍を貸し出している利用者の社員番号が格納されている。人事系のシステムで管理している社員表と結合することで、氏名と連絡先が検索できる。
(3) 返却されたら、貸出日、返却予定日及び社員番号にはnullを設定する。設問1:
問題文を見る データベースの再構築に当たり、利用者と窓口担当者から要望を提出してもらった。解答群に示した要望のうち、従来の書籍表(図1)及び社員表からは検索できない情報を二つ選べ。
解答群
ア:現在、貸出中でない書籍の一覧
イ:現在、貸出中の書籍の一覧
ウ:現在、書籍を貸出中の利用者の連絡先
エ:書籍ごとの累積貸出回数
オ:返却予定日を過ぎても貸出中の書籍の一覧
カ:利用者ごとの貸出履歴
模範解答
エカ
解説
解答の導き方
この問題では、従来の書籍表と社員表を使って調べられる情報と、調べられない情報を区別します。
書籍表には、書籍そのものの情報に加えて、現在の貸出状況が記録されています。問題文には、貸出日と返却予定日が「null」の書籍は貸し出されていないとあります。ここでのnullは、値が設定されていない状態です。
そのため、次の情報は検索できます。
-
ア:現在、貸出中でない書籍の一覧
貸出日がnullになっている書籍を探せば分かります。 -
イ:現在、貸出中の書籍の一覧
貸出日がnullでない書籍を探せば分かります。 -
ウ:現在、書籍を貸出中の利用者の連絡先
書籍表には、貸出中の利用者の社員番号が記録されています。問題文には、社員表と結合すると氏名と連絡先を検索できるとあります。結合とは、共通する項目を手掛かりに複数の表を組み合わせて調べることです。社員番号を使えば、貸出中の書籍と利用者の連絡先を対応付けられます。 -
オ:返却予定日を過ぎても貸出中の書籍の一覧
貸出中かどうかは貸出日から分かり、返却予定日も書籍表に記録されています。現在の日付と返却予定日を比べれば、返却予定日を過ぎた書籍を探せます。
一方、従来の書籍表には、現在の貸出状況しか残りません。問題文には、返却されたら貸出日、返却予定日及び社員番号にnullを設定するとあります。つまり、返却後は、その貸出がいつ、誰によって行われたかを示す情報が書籍表から消えます。
-
エ:書籍ごとの累積貸出回数
過去に何回貸し出されたかを記録する項目がありません。返却後の貸出情報も消えるため、累積回数を数えられません。 -
カ:利用者ごとの貸出履歴
現在貸出中の利用者は分かりますが、返却済みの貸出情報は残っていません。そのため、利用者が過去にどの書籍を借りたかをたどれません。
したがって、従来の書籍表と社員表から検索できない情報は、過去の貸出記録を必要とするエとカです。
誤りやすいポイント
-
貸出中の情報と貸出履歴を混同しないようにします。
現在貸出中かどうかは分かりますが、返却済みの貸出まで分かるとは限りません。 -
社員表との結合で分かる情報の範囲に注意します。
社員番号から利用者の連絡先は調べられます。しかし、返却後に消えた貸出情報までは復元できません。 -
返却予定日が記録されているだけで、履歴が残るとは限りません。
返却予定日を使って現在の延滞状況は調べられますが、返却後の過去の貸出状況は調べられません。
FAQ
Q: nullは、貸出日が分からないという意味ですか?
A: この問題の書籍表では、貸出日などがnullの書籍は「貸し出されていない」と説明されています。したがって、貸出日がnullなら現在は貸出中でないと判断できます。
A: この問題の書籍表では、貸出日などがnullの書籍は「貸し出されていない」と説明されています。したがって、貸出日がnullなら現在は貸出中でないと判断できます。
Q: 社員表があれば、利用者ごとの貸出履歴も分かりませんか?
A: 社員表から分かるのは社員の情報です。返却後の貸出記録が書籍表に残っていないので、過去の貸出履歴は分かりません。
A: 社員表から分かるのは社員の情報です。返却後の貸出記録が書籍表に残っていないので、過去の貸出履歴は分かりません。
Q: 累積貸出回数を調べるには、どのような情報が必要ですか?
A: 貸出のたびに記録を残し、その記録を数えられるようにする必要があります。現在の貸出状況だけでは、過去の回数を確認できません。
A: 貸出のたびに記録を残し、その記録を数えられるようにする必要があります。現在の貸出状況だけでは、過去の回数を確認できません。
関連キーワード: 関係データベース、NULL、表結合、履歴データ、データ保持
設問2:
問題文を見る 利用者と窓口担当者からの要望を踏まえ、データベースを図2に示す表構成で再構築して、運用を始めた。運用開始後に延滞したことがある利用者の社員番号と、延滞した書籍名を、社員番号の昇順に表示したい。次のSQL文のに入れる正しい答えを、解答群の中から選べ。ここで、SQL文中のCURRENT_DATE値関数は、現在の日付をDATE型で返却する。
〔貸出表に関する説明〕
(1) 1冊の貸出しに対して一意の貸出番号を付与し、貸出表に情報を記録する。
(2) 返却日には、返却された日付を格納する。返却日がnullの書籍は、貸出中であることを表す。
(3) 書籍が返却された後も、貸出表に記録された情報は残す。
(4) 貸出日、返却予定日及び返却日はDATE型である。
SELECT 貸出表.社員番号, 書籍表.書籍名
FROM 書籍表, 貸出表
WHERE a
ORDER BY 貸出表.社員番号
解答群
ア:書籍表.書籍番号 = 貸出表.書籍番号 AND (貸出表.返却日 > 貸出表.返却予定日 OR (貸出表.返却日 IS NULL AND 貸出表.返却予定日 < CURRENT_DATE))
イ:書籍表.書籍番号 = 貸出表.書籍番号 AND (貸出表.返却日 BETWEEN 貸出表.貸出日 AND 貸出表.返却予定日 OR 貸出表.返却日 IS NULL OR 貸出表.返却予定日 < CURRENT_DATE)
ウ:書籍表.書籍番号 = 貸出表.書籍番号 AND 貸出表.返却日 != 貸出表.返却予定日
エ:書籍表.書籍番号 = 貸出表.書籍番号 AND 貸出表.返却日 IS NOT NULL模範解答
a:ア
解説
解答の導き方
この設問では、過去または現在の貸出記録から、延滞した貸出を見つけます。延滞には、「返却が予定日より遅れた場合」と「まだ返却されておらず、返却予定日を過ぎている場合」の2通りがあります。
-
書籍表と貸出表を、書籍番号で結び付けます。
SQL(Structured Query Language:データベースに問い合わせたり、データを操作したりするための言語)のWHEREは、検索する行を条件で絞る部分です。書籍表の書籍名と貸出表の貸出情報を対応させるには、書籍番号が同じ行どうしを結び付ける必要があります。したがって、条件に「書籍表.書籍番号 = 貸出表.書籍番号」が必要です。このように、表どうしの関連する行を結び付けることを結合といいます。 -
返却済みの貸出について、延滞かどうかを調べます。
返却日が記録されている貸出では、返却日が返却予定日より後なら延滞です。つまり、条件は「貸出表.返却日 > 貸出表.返却予定日」となります。返却日が予定日と同じ場合や、それより前の場合は延滞ではありません。 -
貸出中の書籍について、延滞かどうかを調べます。
貸出表に関する説明では、「返却日がnullの書籍は、貸出中」とあります。NULL(値が入っていないことを表す記号)の場合、返却日はまだ分からないため、返却日と返却予定日を直接比べることはできません。そこで、「貸出表.返却日 IS NULL」で貸出中かどうかを確認し、返却予定日が現在の日付より前かを調べます。条件は「貸出表.返却予定日 < CURRENT_DATE」です。返却予定日が今日と同じ場合は、まだ予定日を過ぎていないため、この条件には当てはまりません。 -
2通りの延滞条件をORでまとめます。
返却済みの延滞と、貸出中の延滞のどちらかに当てはまればよいので、2つの条件をORでつなぎます。書籍番号で表を結び付ける条件と合わせると、アの条件になります。 -
社員番号の昇順で並べます。
SQLのORDER BYは、検索結果を指定した項目で並べ替える部分です。「ORDER BY 貸出表.社員番号」とあるため、社員番号の昇順で表示できます。ASC(昇順を指定する語)が省略されていますが、指定がない場合は昇順になります。
誤りやすいポイント
-
返却日がNULLなら、すべて延滞というわけではありません。
まだ貸出中でも、返却予定日を過ぎていなければ延滞ではありません。そのため、貸出中の場合は返却予定日とCURRENT_DATEの比較も必要です。 -
返却予定日を過ぎていても、すでに返却済みなら実際の返却日を確認します。
返却予定日が過去の日付でも、返却日が返却予定日以前なら延滞ではありません。アは、返却済みの場合と貸出中の場合を分けて判定しています。 -
イは、延滞ではない貸出も含めてしまいます。
返却日がNULLなら返却予定日を過ぎていない貸出も条件に合います。また、返却予定日がCURRENT_DATEより前であれば、すでに予定どおり返却された貸出も条件に合ってしまいます。 -
ウは、返却日と返却予定日が異なることだけを調べています。
予定日より早く返却した場合も日付は異なります。また、返却日がNULLの貸出は、通常の日付比較では延滞と判定できません。 -
エは、返却済みかどうかしか判定しません。
返却済みの貸出をすべて対象にするため、予定どおり返却された貸出も含まれます。一方、延滞中の貸出は返却日がNULLなので対象外になります。
FAQ
Q: なぜ返却日がNULLのときだけCURRENT_DATEと比べるのですか?
A: 返却済みなら、実際の返却日と返却予定日を比べれば延滞か分かります。返却日がNULLなら実際の返却日は分からないため、現在の日付と返却予定日を比べて、まだ貸出中のまま延滞しているかを調べます。
A: 返却済みなら、実際の返却日と返却予定日を比べれば延滞か分かります。返却日がNULLなら実際の返却日は分からないため、現在の日付と返却予定日を比べて、まだ貸出中のまま延滞しているかを調べます。
Q: 返却予定日が今日の場合、貸出中でも延滞ですか?
A: いいえ。このSQLの条件は「返却予定日 < CURRENT_DATE」です。返却予定日が今日と同じ場合は条件に合わないため、延滞として扱いません。
A: いいえ。このSQLの条件は「返却予定日 < CURRENT_DATE」です。返却予定日が今日と同じ場合は条件に合わないため、延滞として扱いません。
Q: 過去の貸出記録を残すと、何が分かりますか?
A: 貸出表に「返却された後も」情報を残すことで、過去の貸出についても、返却日と返却予定日を比べて延滞の有無を確認できます。
A: 貸出表に「返却された後も」情報を残すことで、過去の貸出についても、返却日と返却予定日を比べて延滞の有無を確認できます。
関連キーワード: 関係データベース、SQL、NULL、日付比較、結合、ORDER BY
設問3:
問題文を見る 貸出回数が多い順に書籍番号、書籍名及び貸出回数を表示したい。次のSQL文のに入れる正しい答えを、解答群の中から選べ。
SELECT 書籍表.書籍番号, 書籍表.書籍名, b AS 貸出回数
FROM 書籍表, 貸出表
WHERE 書籍表.書籍番号 = 貸出表.書籍番号
GROUP BY 書籍表.書籍番号, 書籍表.書籍名
ORDER BY 貸出回数 DESC
解答群
ア:COUNT(*)
イ:MAX(書籍表.書籍番号)
ウ:SUM(貸出表.貸出番号)
エ:貸出表.貸出番号
オ:書籍表.書籍番号
模範解答
b:ア
解説
解答の導き方
このSQLは、書籍ごとに貸出回数を数え、その回数が多い順に並べるものです。SQL(Structured Query Language:データベースに検索や集計を指示する言語)の各部分を順に見ていきます。
-
書籍表と貸出表を、同じ書籍番号の行どうしで対応させます。WHERE句には「書籍表.書籍番号 = 貸出表.書籍番号」とあります。これにより、貸出記録と、その貸出対象である書籍の情報を結び付けます。貸出表では貸出の記録が1件ごとに1行で管理されています。したがって、ある書籍が何度も貸し出されていれば、その書籍番号に対応する貸出表の行も複数あります。
-
書籍ごとに貸出記録をまとめます。GROUP BY句では「書籍表.書籍番号, 書籍表.書籍名」を指定しています。これは、書籍番号と書籍名が同じ行を一つのグループにまとめる指定です。つまり、書籍ごとに、その書籍に対応する貸出表の行が一つのグループに集まります。
-
グループ内の行数を数えます。貸出回数を求めるには、各グループに何件の貸出記録があるかを数えればよいです。行数を数えるには、COUNT()を使います。COUNT()は、対象となる行の数を数える集約関数です。集約関数とは、複数の行をまとめて一つの値にする関数です。そのため、bにはCOUNT(*)が入ります。集計結果には「貸出回数」という名前が付けられます。図2では、貸出表に返却済みの記録と、返却日がnullの記録があります。このSQLには返却日で絞り込む条件がないため、返却済みの記録も含めて貸出記録の行数を数えます。
-
貸出回数が多い順に並べます。ORDER BY 貸出回数 DESCは、貸出回数を基準に降順で並べる指定です。DESC(descending:降順)によって、回数の多い書籍が先に表示されます。ほかの選択肢では、MAX(書籍表.書籍番号)は書籍番号の最大値、SUM(貸出表.貸出番号)は貸出番号の合計になります。どちらも貸出記録の件数ではありません。貸出表.貸出番号や書籍表.書籍番号だけを指定しても、行数を数える処理にはなりません。
誤りやすいポイント
-
番号を合計すれば件数になると思う貸出番号は貸出記録を区別するための番号です。番号を足しても貸出回数にはなりません。件数を数えるときはCOUNT(*)を使います。
-
MAXを使えば一番多い回数が分かると思うMAXは、値の中から最大の値を選ぶ関数です。ここで書籍番号に使うと、貸出回数ではなく書籍番号の最大値を求めます。
-
返却済みの貸出記録は数えないと思うこのSQLには返却日を条件にした指定がありません。そのため、返却済みかどうかにかかわらず、貸出表の記録を数えます。
FAQ
Q: COUNT(*)とCOUNT(列名)は同じですか?
A: COUNT()は行数を数えます。COUNT(列名)は、その列の値がnullではない行の数を数えます。この問題では貸出記録の行数を数えたいので、COUNT()を使います。
Q: なぜGROUP BY句が必要なのですか?
A: 書籍ごとに貸出回数を求めるためです。GROUP BY句で書籍ごとに貸出記録をまとめてから、COUNT(*)で各グループの行数を数えます。
Q: 貸出番号が連番なら、最大の貸出番号から回数を求められますか?
A: このSQLでは、番号の大小ではなく貸出記録の行数を数えます。番号は記録を識別するためのものであり、貸出回数そのものではありません。
関連キーワード: SQL、集約関数、COUNT関数、GROUP BY句、ORDER BY句
設問4:
問題文を見る 資料室に設置されている端末からだけでなく、利用者が自席のPCからも書籍を検索できるようにしたところ、貸出実績の増加と利用者からのアクセスの急増に伴い、書籍名を入力して貸出中か否かを表示する処理で、レスポンスの低下が顕在化した。レコード件数を確認したところ、書籍表が865件、貸出表が10,382件だった。
そこで、インデックスを設定して検索性能の向上を図ることにした。インデックスの設定によって最も効果が期待できる項目として適切なものを、解答群の中から選べ。
解答群
ア:書籍表.書籍名
イ:貸出表.書籍番号
ウ:貸出表.社員番号
エ:貸出表.貸出日
オ:貸出表.返却日
模範解答
イ
解説
解答の導き方
設問では、「書籍名を入力して貸出中か否かを表示する処理」を速くするため、どの項目にインデックスを設定すると効果が大きいかを考えます。
インデックスとは、表の中から条件に合う行を見つけやすくするための仕組みです。本の索引を使うと目的のページを探しやすくなるのと同じように、データを一行ずつ調べる手間を減らせます。
- まず、入力された書籍名から、対象の書籍を探します。書籍名と書籍番号は書籍表にあります。書籍表の件数は865件です。
- 次に、その書籍が貸出中かどうかを調べます。そのためには、貸出表から対象の書籍の貸出記録を探し、返却日を確認します。図2では、返却日がnull(値が設定されていない状態)の記録と、返却日が設定された記録があります。
- 書籍表で見つけた書籍と貸出表の記録を対応付ける項目は、書籍番号です。このように、複数の表を共通する項目で対応付ける処理を表の結合といいます。
貸出表の件数は10,382件です。貸出表から対象の書籍の記録を探すときに使う貸出表.書籍番号にインデックスを設定すれば、貸出表の行を一つずつ調べる手間を減らせます。このため、選ぶ項目はイの貸出表.書籍番号です。
誤りやすいポイント
- 書籍名を入力するので、書籍表.書籍名に注目しがちです。書籍名の検索には役立ちますが、その後、貸出表から対象の書籍の貸出記録を探す処理もあります。貸出表の件数の方が多く、書籍番号が表同士を対応付ける項目なので、貸出表.書籍番号が適切です。
- 返却日も貸出中かどうかの判断に使います。しかし、返却日だけでは、どの書籍の貸出記録なのかを特定できません。まず書籍番号で対象を絞り込むことが重要です。
- 社員番号や貸出日は、今回の処理で書籍表と貸出表を対応付けるための項目ではありません。入力された書籍名から、その書籍の貸出状況を調べるという処理の流れに沿って判断しましょう。
FAQ
Q: 貸出表.書籍番号には、同じ番号が複数回登場する可能性があります。それでもインデックスは有効ですか?
A: はい。有効です。インデックスは値が一つの行だけに対応する場合に限らず、同じ値をもつ複数の行を探す場合にも役立ちます。
A: はい。有効です。インデックスは値が一つの行だけに対応する場合に限らず、同じ値をもつ複数の行を探す場合にも役立ちます。
Q: 返却日が貸出状況の判断に使われるなら、貸出表.返却日にインデックスを設定する方がよいのではありませんか?
A: 今回は、特定の書籍の貸出記録を探してから返却日を確認します。返却日だけを条件にすると、対象の書籍以外の記録も検索されるため、書籍番号で探す方が処理の流れに合っています。
A: 今回は、特定の書籍の貸出記録を探してから返却日を確認します。返却日だけを条件にすると、対象の書籍以外の記録も検索されるため、書籍番号で探す方が処理の流れに合っています。
関連キーワード: インデックス、表結合、検索条件、検索性能



