令和3年度 秋期 応用情報技術者試験 午後 問題 問6 企業向け電子書籍サービス追加に伴うデータモデルの拡張とSQLの作成
テクノロジデータベース
学習ガイド
個人向け電子書籍サービスに企業向けの機能を追加するための、データベース設計と実装に関する問題です。E-R図のエンティティ間のリレーションの特定、書籍の割り当てや一覧取得を行うSQL文の完成、および複数ユーザーによる同時更新時の排他制御の目的が問われます。業務のルールや処理の流れの記述から必要なデータ項目を洗い出し、SQLの構文とテーブルの結合条件を組み立てます。
この記事で押さえる論点
- E-R図からエンティティ間の関連や必要な属性を読み取ることができる
- 埋込み変数を用いたデータ挿入や集計のSQL文を記述できる
- トランザクションの同時実行制御における専有ロックの必要性を説明できる
- 個人の利用アカウントと企業のアカウントを統合するためのデータ設計を説明できる
出題情報
- 出題
- 2021(R3)秋 応用情報技術者 午後 問6
- 配点
- 20点満点
- 模範解答
- 公表(設問ごとに掲載)
出題趣旨・採点講評(IPA 公表)
近年,テレワークの普及に伴い,インターネット利用を前提とする新しいサービスが増えつつある。
本問では,企業向け電子書籍サービスを題材に,E-R図やSQL文に関する基本的な理解,トランザクション処理における同時実行制御に関する理解,業務要件からデータモデルを実装する能力を問う。
問6では,企業向け電子書籍サービスを題材に,E-R図,SQL文,トランザクション処理における同時実行制御,データモデルなどについて出題した。全体として正答率は平均的であった。
問題本文
企業向け電子書籍サービスの追加設計と実装に関する次の記述を読んで,設問1〜4に答えよ。
H社は,個人会員向けに電子書籍の販売及び閲覧サービス(以下,既存サービスという)を提供する中堅企業である。近年,テレワークの普及に伴い,企業での電子書籍の需要が高まってきた。そこで,既存サービスに加え,企業向け電子書籍サービス(以下,新サービスという)を開発することになった。
新サービスの開始に向けて,企業向け書籍購入サイトを新たに作成し,既存サービスで提供している電子書籍リーダを改修する。新サービスの機能概要を表1に,検討したデータベースのE-R図の抜粋を図1に示す。
このデータベースでは,E-R図のエンティティ名を表名にし,属性名を列名にして,適切なデータ型で表定義した関係データベースによって,データを管理する。

図の説明テキスト
表1 新サービスの機能概要
| No. | 機能名 | 概要 |
|---|---|---|
| 1 | 一括購入 | 企業の一括購入担当者が,電子書籍を一括購入する。購入した電子書籍を企業の社員に割り当てる方法には,次の二つがある。 (1) 一括購入担当者が,配布対象の社員にあらかじめ割り当てておく方法 (2) 社員が,未割当の一括購入された電子書籍を割当依頼する方法 |
| 2 | 企業補助 | 社員が,自己啓発に役立つビジネスや技術など特定の分類の電子書籍を購入する。その際,企業が購入額の一部を負担する。ただし,企業は負担する上限金額を書籍分類ごとに設定する。 |
| 3 | 割引購入 | 社員が,個人として読みたい本や雑誌などの電子書籍を購入する。その際,それぞれの企業が H 社と契約した一定の割引率を適用した価格で購入できる。 |
| 4 | 書籍閲覧 | 社員が,電子書籍リーダに,H 社が付与した企業 ID,社員 ID 及び社員パスワードを用いてログインし,No. 1〜3で購入した電子書籍を閲覧する。 電子書籍リーダにログインすると,一括購入で割り当てられた電子書籍や,社員が購入した電子書籍が一覧表示され,各電子書籍を選択して閲覧できる。 |
〔一括購入機能の社員割当処理の作成〕
表1中の一括購入機能の概要(2)にある,社員が割当依頼した電子書籍を割り当てる処理を考える。検討した処理の流れを表2に示す。ここで,“:一括購入ID”は割当依頼された一括購入IDを,“:企業ID”及び“:社員ID”は割当依頼した社員の企業IDと社員IDを格納する埋込み変数である。

図の説明テキスト
図1 検討したデータベースの E-R 図 (抜粋)
エンティティと属性(主キーは実線下線、外部キーは破線下線):
- 書籍: 書籍ID(主キー), 書籍名, 書籍分類ID(外部キー), 定価
- 書籍分類: 書籍分類ID(主キー), 書籍分類名
- 企業補助: 企業補助ID(主キー), 企業ID(外部キー), 書籍分類ID(外部キー), 補助率, 補助上限金額
- 企業: 企業ID(主キー), 企業名, b
- 社員: 企業ID(主キー), 社員ID(主キー), 社員パスワード
- 社員書籍購入: 社員書籍購入ID(主キー), 社員書籍購入日時, 企業ID(外部キー), 社員ID(外部キー), c, 企業負担金額, 社員負担金額
- 購入: 購入ID(主キー), 購入日時, 個人会員ID(外部キー), 書籍ID(外部キー)
- 個人会員: 個人会員ID(主キー), 個人会員パスワード, 個人会員名
- 一括購入: 一括購入ID(主キー), 一括購入日時, 企業ID(外部キー), 書籍ID(外部キー), 一括購入担当者名, 一括購入数量, 一括購入金額
- 一括購入割当: 一括購入ID(主キー), 社員ID(主キー), 企業ID(主キー)
リレーションシップ (1対多の「多」側に矢印):
- 書籍分類 から 書籍 (1対多)
- 書籍分類 と 企業補助 の間のリレーションシップ線上にa
- 企業 から 企業補助 (1対多)
- 企業 から 一括購入 (1対多)
- 企業 から 社員 (1対多)
- 書籍 から 社員書籍購入 (1対多)
- 書籍 から 一括購入 (1対多)
- 書籍 から 購入 (1対多)
- 個人会員 から 購入 (1対多)
- 社員 から 社員書籍購入 (1対多)
- 社員 から 一括購入割当 (1対多)
- 一括購入 から 一括購入割当 (1対多)
凡例:
- 実線: 1対1
- 矢印付き実線: 1対多
- 両矢印付き実線: 多対多
- エンティティの枠内は上から「エンティティ名」「属性名...」
- 属性名の実線の下線は主キー、破線の下線は外部キーを示す。主キーの実線が付いている属性名には、外部キーの破線を付けない。

図の説明テキスト
表2 検討した処理の流れ
| 手順 | 処理概要 | 使用するSQL文 |
|---|---|---|
| 1 | 社員が割当依頼した一括購入IDから、一括購入数量を取得する。 | SELECT 一括購入数量 FROM 一括購入 WHERE 一括購入ID = :一括購入ID |
| 2 | 社員が割当依頼した一括購入IDのうち、現在割り当てられている数量を取得する。 | SELECT d FROM 一括購入割当 WHERE 一括購入ID = :一括購入ID |
| 3 | 手順1で取得した数量が、手順2で取得した数量より e 場合、手順4に進む。そうでない場合、処理を終了する。 | なし |
| 4 | 割当依頼した社員に一括購入IDを割り当てる。 | INSERT INTO 一括購入割当 (一括購入ID, 社員ID, 企業ID) f |
表2のレビューを実施したところ,処理の流れやSQL文に問題はないが,①トランザクションの同時実行制御には専有ロックを用いるように,とのアドバイスを受けた。
〔書籍閲覧機能の作成〕
電子書籍リーダに,社員がログインした際,閲覧可能な重複を含まない書籍の一覧を取得するSQL文を図2に示す。ここで,“:企業ID”及び“:社員ID”は,ログインした社員の企業IDと社員IDを格納する埋込み変数である。また,図2のcには,図1のcと同じ字句が入る。

図の説明テキスト
図2 閲覧可能な重複を含まない書籍の一覧を取得する SQL文
SQLソースコードの枠:
SELECT sk. c
FROM 社員書籍購入 sk
WHERE sk.企業ID = :企業ID AND sk.社員ID = :社員ID
g
SELECT ik. c
FROM 一括購入 ik
INNER JOIN 一括購入割当 iw
h
WHERE ik.企業ID = :企業ID AND iw.社員ID = :社員ID
〔書籍閲覧機能の改善〕
書籍閲覧機能のレビューを実施したところ,既存サービスを個人で利用している社員は,電子書籍リーダのログインIDを個人会員IDから企業IDと社員IDに切り替えて利用しなければならず煩雑である,との指摘を受けた。
そこで,電子書籍リーダに個人会員IDを用いてログインした際,社員として閲覧できる書籍も一覧に追加して閲覧できるように,E-R図に新たに②一つエンティティを追加し,電子書籍リーダに③一つ画面を追加した上で書籍閲覧機能に改修を施した。
設問と解答・解説
空欄 a に入れる適切なエンティティ間の関連を答えよ。
模範解答
→
採点基準
- 2点: 「→」(書籍分類を1側、企業補助を多側とする1対多。「書籍分類から企業補助への1対多」と言葉で向きを示したものも可)と記述されている。
- 1点: 「1対多」とだけ書き、どちらが多側かを示していない。
- 0点: 向きが逆(←)、線のみ(1対1)、↔(多対多)、無回答。
解説
解説
- E-R図の関連を問う問題です。
- 図1の「書籍分類」と「企業補助」の間の関連
aについて考えます。 - 表1「新サービスの機能概要」の「No. 2 企業補助」には、「企業は負担する上限金額を書籍分類ごとに設定する」と記載されています。
- これは、1つの企業が複数の企業補助(書籍分類ごとの上限金額)を持つことを意味します。図1のE-R図を見ると、「企業」から「企業補助」へ「1対多(→)」のリレーションシップが設定されています。
- 一方、「書籍分類」は複数の企業で企業補助の対象となり得ます。また、「企業補助」エンティティは「企業ID」と「書籍分類ID」を外部キーとして持つ交差エンティティ(連関エンティティ)の役割を果たしています。
- したがって、「書籍分類」1つに対して「企業補助」のレコードが複数存在し得るため、「書籍分類」から「企業補助」への関連は「1対多」となります。
- 凡例の通り、1対多の「多」側に矢印を向けるため、正解は「→」となります。
高得点のポイント
- 1対多の関連を示す記号を、問題の凡例に従って正確に記述できているかどうかが評価されます。
空欄 b に入れる適切な属性名を答えよ。
模範解答
割引率
採点基準
- 2点: 「割引率」(「企業割引率」など同義の表記も可)と記述されている。
- 1点: 割引に関する属性だが率でない(割引額・割引価格)。
- 0点: 補助率など。
解説
解説
- 図1の「企業」エンティティの属性
bを問う問題です。 - 表1「No. 3 割引購入」に、「それぞれの企業が H 社と契約した一定の 割引率 を適用した価格で購入できる」と記載されています。
- つまり、企業ごとに特定の「割引率」が設定され、管理される必要があります。
- したがって、「企業」エンティティには属性として「割引率」が必要となります。
高得点のポイント
- 企業エンティティに追加すべき属性を、表1の機能概要から正確に読み取り解答できているかどうかが評価されます。
空欄 c に入れる適切な属性名を答えよ。
模範解答
書籍ID
採点基準
- 2点: 「書籍ID」と記述されている(「書籍ID(外部キー)」のように外部キーであることを添えたものも可。添えていなくても減点しない)。
- 1点: 書籍を参照する属性であることは分かるが属性名が図1と異なる(書籍番号・書籍コードなど)。
- 0点: 書籍名・定価・書籍分類IDなど。
解説
解説
- 図1の「社員書籍購入」エンティティの属性
cを問う問題です。 - 表1「No. 2 企業補助」や「No. 3 割引購入」において、社員が電子書籍を購入した際の履歴・明細となるエンティティが「社員書籍購入」です。
- 現在の「社員書籍購入」には、主キーの「社員書籍購入ID」や「社員書籍購入日時」、外部キーの「企業ID」「社員ID」などがありますが、どの書籍を購入したかを示す情報が不足しています。
- 図1のE-R図を見ると、「書籍」エンティティから「社員書籍購入」エンティティに対して「1対多」のリレーションシップ(矢印)が引かれています。
- 凡例のルールに従うと、リレーションシップの「多」側である「社員書籍購入」エンティティには、「1」側である「書籍」エンティティの主キー「書籍ID」が外部キーとして含まれる必要があります。
- したがって、空欄
cには「書籍ID」が入ります。公式解答例では、図1の凡例に従って「書籍ID」に外部キーを示す破線の下線が付きます。
高得点のポイント
- 社員書籍購入エンティティに必要な外部キーを、E-R図のリレーションシップに基づいて正確に解答できているかどうかが評価されます。
設問1のbは,正答率が平均的であった。新サービスの機能概要中にある割引購入とE-R図を注意深く読んで,正答を導いてほしい。
設問2
〔一括購入機能の社員割当処理の作成〕について,(1),(2)に答えよ。
表2中の d に入れる適切な字句を答えよ。
模範解答
COUNT(*)
採点基準
- 1点: 「COUNT(*)」、又は一括購入割当の行数になる同値な式(COUNT(社員ID)、COUNT(企業ID) などNULLにならない列のCOUNT)が記述されている。
- 0点: SUM・MAX など行数にならないもの。
解説
解説
- 表2の「一括購入機能の社員割当処理」の手順2のSQL文に関する問題です。
- 手順2の処理概要は「社員が割当依頼した一括購入IDのうち、現在割り当てられている数量を取得する」ことです。
- 「一括購入割当」エンティティは、一括購入IDごとに割り当てられた社員の組み合わせ(一括購入ID、社員ID、企業ID)を1行(1レコード)として管理します。
- したがって、「現在割り当てられている数量」を取得するには、「一括購入割当」表から指定された
:一括購入IDに一致するレコードの行数をカウントすればよいことになります。 - 行数をカウントするSQLの集約関数は
COUNT(*)であるため、空欄dにはCOUNT(*)が入ります。
高得点のポイント
- レコード数を取得するための適切なSQL集約関数(
COUNT(*)など)を正確に記述できているかどうかが評価されます。
表2中の e に入れる適切な字句を答えよ。
模範解答
大きい
採点基準
- 1点: 「大きい」(「多い」も可)と記述されている。
- 0点: 「以上」(等しいときは割当済みが上限に達している)・「小さい」など。
解説
解説
- 表2の手順3の処理ロジックに関する問題です。
- 手順1で「一括購入数量」(上限となる割り当て可能な総数)を取得し、手順2で「現在割り当てられている数量」(既に割り当て済みの数)を取得しています。
- 新たに社員へ電子書籍の割り当てを行うためには、未割り当ての残数があること、すなわち「手順1で取得した数量」が「手順2で取得した数量」よりも大きい必要があります。
- したがって、割り当て処理(手順4)に進むための判定条件として、空欄
eには「大きい」が入ります。
高得点のポイント
- 割り当ての可否を判定するロジックを理解し、数量の比較条件として適切な字句を解答できているかどうかが評価されます。
表2中の f に入れる適切な字句を答えよ。
模範解答
VALUES ( :一括購入ID, :社員ID, :企業ID )
採点基準
- 1点: 正解の字句や式が正確に記述されている。
- 0点: 無解答、または全く異なる内容が記述されている。
解説
解説
- 表2の手順4のSQL(
INSERT文)に関する問題です。 INSERT INTO文で列名リスト(一括購入ID, 社員ID, 企業ID)が指定されているため、その後に挿入する実際の値のリストをVALUES句で指定する構文となります。- 問題文の〔一括購入機能の社員割当処理の作成〕の冒頭に、「“:一括購入ID”は割当依頼された一括購入IDを、“:企業ID”及び“:社員ID”は割当依頼した社員の企業IDと社員IDを格納する埋込み変数である」と定義されています。
- したがって、列名リストに対応する順序でこれらの埋込み変数を指定し、
VALUES ( :一括購入ID, :社員ID, :企業ID )と記述するのが正解です。
高得点のポイント
- INSERT文の
VALUES句の構文を理解し、埋込み変数を用いて正確に記述できているかどうかが評価されます。
本文中の下線①の専有ロックを用いなかった場合,どのような問題が発生するか。30字以内で述べよ。
模範解答
一括購入数量より多い数量の書籍を割り当ててしまう問題
採点基準
- 1点: 「一括購入数量より多い数量」「上限を超える」など、数量超過が発生する事象を正しく指摘できている。
- 0点: 数量超過に関する言及がない、または事象の捉え方が誤っている。
- 1点: 「〜してしまう問題」「〜が割り当てられる」など、文脈に沿った適切な表現で簡潔にまとめられている。
- 0点: 文章の意図が不明確、または論理的な帰結として不適切な記述となっている。
解説
解説
- トランザクションの同時実行制御(排他制御)に関する問題です。
- 表2の処理では、手順1〜2で空き数量を確認し、手順3の判定を経て、手順4で割り当て(INSERT)を行っています。
- 専有ロック(排他ロック)を用いない場合、複数の社員が同じ一括購入IDに対して同時に割当依頼を行った際に問題が生じます。
- 具体的には、複数のトランザクションが同時に手順1〜2を実行し、同じ「現在割り当てられている数量」を取得してしまいます。
- その結果、実際には残り1枠しかないにもかかわらず、複数のトランザクションが同時に手順3の「割り当て可能」という判定を通過し、それぞれ手順4のINSERT処理を実行してしまいます。
- これにより、企業が購入した「一括購入数量」を超えて、書籍が多くの社員に割り当てられてしまう(オーバーコミット)という事象が発生します。
高得点のポイント
- 知識・理解度(内容): 同時実行制御が不十分なことにより、上限(一括購入数量)を超える割り当てが発生してしまうという事象を正しく理解し、指摘できているか。
- 論理性(構造): 「〜してしまう問題」など、発生する矛盾や不整合の具体的な内容を、指定された文字数(30字)以内で簡潔かつ明確に記述できているか。
設問2(1)のfは,正答率が低かった。INSERT文を用いたデータの挿入は,重要なデータ操作の一つである。基本的な構文だけではなく,埋込み変数を用いた記述方法についても理解してほしい。
空欄 g に入れる適切な字句又は式を答えよ。
模範解答
UNION
採点基準
- 2点: 「UNION」(大文字小文字は問わない)と記述されている。
- 1点: 「UNION ALL」(結果を合わせる意図は合うが重複が残る)と記述されている。
- 0点: INTERSECT・EXCEPT・JOIN など。
解説
解説
- 図2の書籍閲覧一覧を取得するSQL文に関する問題です。
- 問題文に「閲覧可能な重複を含まない書籍の一覧を取得するSQL文」と指定されています。
- SQLの前半では
社員書籍購入表から社員が自分で購入した書籍 (sk.書籍ID) を取得し、後半では一括購入表と一括購入割当表を結合して一括購入で割り当てられた書籍 (ik.書籍ID) を取得しています。(※空欄cは設問1で求めた書籍IDです) - これら2つの
SELECT文の結果を統合し、かつ重複を排除して1つの結果セットにするためには、集合演算子であるUNIONが必要です。 - 重複を許容する場合は
UNION ALLとなりますが、今回は「重複を含まない」ためUNIONが正解となります。
高得点のポイント
- 複数のSELECT結果を統合し、要件(重複排除)を満たすための適切な集合演算子を記述できているかどうかが評価されます。
空欄 h に入れる適切な字句又は式を答えよ。
模範解答
ON ik.一括購入ID = iw.一括購入ID
採点基準
- 2点: 「ON ik.一括購入ID = iw.一括購入ID」(等号の左右の入替え・空白の有無は問わない。「AND ik.企業ID = iw.企業ID」を加えたものも結果が同じなので可)と記述されている。
- 1点: 結合列は正しいが相関名が欠ける(設問の指示に反する)、又は ON が欠ける。
- 0点: 結合列が誤り(社員ID・企業IDだけで結合など)。
解説
解説
- 図2の後半の
SELECT文におけるINNER JOINの結合条件に関する問題です。 - 結合の対象となる表は
一括購入表(相関名ik)と一括購入割当表(相関名iw)です。 - 図1のE-R図を参照すると、「一括購入」エンティティと「一括購入割当」エンティティは「1対多」の関係にあり、「一括購入」の主キーである「一括購入ID」が「一括購入割当」に外部キーとして保持されています。
- したがって、これら2つの表を正しく結合するための条件(
ON句)は、両表の共通列である一括購入IDが一致することです。 - 問題の指示「表の列名には必ずその表の相関名を付けて答えよ」に従い、
ON ik.一括購入ID = iw.一括購入IDと記述します。
高得点のポイント
- 表の結合条件(
ON句)の構文を理解し、相関名を用いて正確に記述できているかどうかが評価されます。
設問4
〔書籍閲覧機能の改善〕について,(1),(2)に答えよ。
本文中の下線②で追加したエンティティの属性名を全て列挙せよ。
なお,エンティティの属性名に主キーや外部キーを示す下線は付けなくてよい。
模範解答
個人会員ID,企業ID,社員ID
採点基準
- 2点: 個人会員を特定する「個人会員ID」と、社員を特定する「企業ID」「社員ID」の両方を理解し解答できている。
- 1点: いずれかのIDが欠けている、または個人会員IDと社員IDのみ(企業IDが欠けている)などの不完全な理解に留まる。
- 0点: 全く異なる属性を解答している、または紐付けの概念を理解していない。
- 1点: 余分な属性を含まず、必要な3つのIDのみを正確に列挙できている。
- 0点: 不必要な属性が含まれているなど、列挙内容が論理的でない。
解説
解説
- 〔書籍閲覧機能の改善〕において「一つエンティティを追加」した目的と、その属性を問う問題です。
- 改善の目的は、「電子書籍リーダに個人会員IDを用いてログインした際、社員として閲覧できる書籍も一覧に追加して閲覧できるように」することです。
- これは、「既存サービスの個人会員」としてのアカウント情報(個人会員ID)と、「新サービスの社員」としてのアカウント情報(企業IDおよび社員ID)を紐付ける(マッピングする)役割を果たすエンティティが必要であることを意味します。
- このエンティティは、両者のアカウントを関連付けるための交差エンティティとして機能します。
- したがって、追加されるエンティティの属性は、個人会員を特定する「個人会員ID」と、社員を一意に特定する複合キーである「企業ID」「社員ID」の3つとなります。
高得点のポイント
- 知識・理解度(内容): 業務要件の変更に伴い、個人会員側と社員側の両方を紐付けるための識別子(個人会員ID、企業ID、社員ID)を正しく特定できているか。
- 論理性(構造): 余分な属性を含まず、必要な3つのIDのみを正確に列挙できているか。
本文中の下線③とは,どのような画面か。25字以内で述べよ。
模範解答
個人会員が企業IDと社員IDを登録する画面
採点基準
- 1点: 個人会員(個人会員IDでログインした状態)が自分の企業IDと社員IDを登録(入力・紐付け)する画面であることを述べている。
- 0点: 社員のログイン画面・書籍一覧画面など、紐付けの登録でないもの。
- 1点: 行為の主体や対象情報が明確であり、意図が伝わる簡潔な文章になっている。
- 0点: 状況や画面追加の意図が不明確な記述となっている。
解説
解説
- 〔書籍閲覧機能の改善〕において、追加したエンティティにデータを登録するための「画面」の役割を問う問題です。
- 改善の目的は「電子書籍リーダに個人会員IDを用いてログインした際」に社員としての書籍も閲覧できるようにすることです。
- このためには、システム上で個人会員IDと(企業ID・社員ID)の紐付けデータが事前に作成されている必要があります。
- したがって、個人会員としてログインしているユーザー(社員本人)に対して、自身の「企業ID」と「社員ID」を入力させ、システムに紐付け情報を登録させるためのインターフェースが必要となります。
- よって、追加する画面は「個人会員が企業IDと社員IDを登録する画面」となります。
高得点のポイント
- 知識・理解度(内容): アカウントの紐付けを行うために、企業IDと社員IDを入力・連携する目的の画面が必要であることを正しく捉えられているか。
- 論理性(構造): 行為の主体(個人会員)や対象情報(企業ID、社員ID)が明確であり、指定された文字数(25字)以内で意図が伝わる簡潔な文章になっているか。
設問4(2)は,正答率が低かった。電子書籍リーダに個人会員IDを用いてログインしている状況において,どのような画面を追加するかを問うたが,その状況や画面追加を考慮しない解答が散見された。落ち着いて問題文を読んで解答するよう心掛けてもらいたい。