令和4年度 春期 応用情報技術者試験 午後 問6 クーポン発行機能のデータモデル設計と排他制御による連番管理方式の選択
テクノロジデータベース
学習ガイド
既存の施設予約サービスに新たなクーポン発行機能を追加する際のDB設計を扱った問題です。E-R図の関連付けや一意性制約の適用、トラフィック集中時におけるクーポン連番の採番方式が主な論点となります。前半は表1のチェック仕様と図1のE-R図を照らし合わせ、外部キーや制約の配置を特定します。後半は図4と図5のSQL文を比較し、排他ロックの有無が処理性能やユーザー操作に与える影響の違いを正確に読み取りましょう。
この記事で押さえる論点
- 業務要件を満たすE-R図のリレーションシップと外部キー制約を定義できる
- UNIQUE制約を用いた業務ルールの実装とその動作特性を説明できる
- 高トラフィック時における楽観的排他制御と悲観的排他制御の長所と短所を比較できる
- 連番管理方式の変更に伴うテーブル定義の変更とCRUD図の操作内容を特定できる
出題情報
- 出題
- 2022(R4)春 応用情報技術者 午後 問6
- 配点
- 20点満点
- 模範解答
- 公表(設問ごとに掲載)
出題趣旨・採点講評(IPA 公表)
提供するオンラインサービスが,商品販売開始や特典提供開始などの特定のタイミングでレスポンス遅延やタイムアウトを発生させることがある。本問では,クーポン発行サービスを題材に,業務特性と使用する関係データベースの設定に応じた適切な排他制御方式,連番管理方式を検討するための知識,技能を問う。
問6では,クーポン発行サービスを題材に,業務特性と使用する関係データベースの設定に応じた適切な排他制御方式,連番管理方式について出題した。全体として正答率は平均的であった。
問題本文
問6 クーポン発行サービスに関する次の記述を読んで,設問1〜4に答えよ。
K社は,インターネットでホテル,旅館及びレストラン(以下,施設という)の予約を取り扱う施設予約サービスを運営している。各施設は幾つかの利用プランを提供していて,利用者はその中から好みのプランを選んで予約する。会員向けサービスの拡充施策として,現在稼働している施設予約サービスに加え,クーポン発行サービスを開始することにした。
発行するクーポンには割引金額が設定されていて,施設予約の際に料金の割引に利用することができる。K社は,施設,又は都道府県,若しくは市区町村を提携スポンサとして,提携スポンサと合意した割引金額,枚数のクーポンを発行する。
クーポン発行に関しては,提携スポンサによって各種制限が設けられているので,クーポンの獲得,及びクーポンを利用した予約の際に,制限が満たされていることをチェックする仕組みを用意する。
提携スポンサによって任意に設定可能なチェック仕様の一部を表1に,クーポン発行サービスの概要を表2に示す。

図の説明テキスト
表1 提携スポンサによって任意に設定可能なチェック仕様(一部)
| 提携スポンサ | クーポンの獲得制限 | クーポンを利用した予約制限 |
|---|---|---|
| 施設 | ・同一会員による同一クーポンの獲得可能枚数を,1枚に制限する(以下,“同一会員1枚限りの獲得制限”という)。 | ・設定した施設だけを予約可能にする。 ・利用金額が設定金額以上の予約だけを可能にする。 |
| 都道府県,市区町村 | ・設定地区に居住する会員だけが獲得可能にする。 | ・設定地区にある施設だけを予約可能にする。 |

図の説明テキスト
表2 クーポン発行サービスの概要
| 利用局面 | 概要 |
|---|---|
| クーポンの照会 | ・発行予定及び発行中クーポンの情報は,会員向けのメール配信によって会員に周知され,施設予約サービスにおいて検索,照会ができる。 |
| クーポンの獲得 | ・発行中のクーポンを利用するためには,会員がクーポン獲得を行う必要がある。 ・クーポン獲得を行える期間は定められている。 ・クーポンの発行枚数が上限に達すると,以降の獲得はできない。 |
| クーポンの利用 | ・獲得したクーポンは,施設予約サービスにおいて料金の割引に利用できる。 ・1枚のクーポンは一つの予約だけに利用できる。 ・クーポンを利用した予約をキャンセルすると,そのクーポンを別の予約に利用できる。 ・クーポンの利用期間は定められていて,期限を過ぎたクーポンは無効となる。 |
〔クーポン発行サービスと施設予約サービスの E-R図〕
クーポン発行サービスと施設予約サービスで使用するデータベース(以下,予約サイトデータベースという)の E-R図(抜粋)を図1に示す。予約サイトデータベースでは,E-R図のエンティティ名をテーブル名に,属性名を列名にして,適切なデータ型で表定義した関係データベースによってデータを管理する。
クーポン管理テーブルの列名の先頭に“獲得制限”又は“予約制限”が付く列は,クーポンの獲得制限,又はクーポンを利用した予約制限のチェック処理で使用し,チェックが必要ない場合には NULL を設定する。“獲得制限_1枚限り”には,“同一会員1枚限りの獲得制限”のチェックが必要なときは 'Y'を,不要なときは NULL を設定する。

図の説明テキスト
図1 予約サイトデータベースのE-R図(抜粋)。以下のエンティティとその属性、リレーションシップが示されている。
【エンティティ】
- 会員(会員コード[主キー], 氏名, 会員住所都道府県コード, 会員住所市区町村コード)
- クーポン管理(クーポンコード[主キー], 発行上限枚数, 割引金額, 獲得可能開始日時, 獲得可能終了日時, 利用期間開始日, 利用期間終了日, 獲得制限_1枚限り, 獲得制限_会員住所都道府県コード, 獲得制限_会員住所市区町村コード, 予約制限_施設コード, 予約制限_最低利用金額, 予約制限_施設住所都道府県コード, 予約制限_施設住所市区町村コード)
- 予約(予約コード[主キー], 会員コード[外部キー], a, b, 利用人数, 利用開始日時, クーポンコード[外部キー], クーポン発行連番[外部キー])
- クーポン明細(クーポンコード[外部キー], クーポン発行連番[外部キー], 獲得会員コード[外部キー], 獲得制限_1枚限り)
- 利用プラン(施設コード[外部キー], プランコード[主キー], 最小利用人数, 最大利用人数, 1名分利用料金)
- 施設(施設コード[主キー], 施設名, 施設住所都道府県コード, 施設住所市区町村コード)
【リレーションシップ】
- 会員 から 予約 へ 1対多の矢印
- 会員 から クーポン明細 へ 1対多の矢印
- クーポン管理 から クーポン明細 へ 1対多の矢印
- 予約 から クーポン明細 へ 1対多の矢印
- 利用プラン から 予約 へ 1対多の矢印
- 利用プラン と 施設 の間にcが付与された結線
【凡例と注記】
- 凡例: 「エンティティ名」, 「属性名(主キー)」, 「属性名(外部キー)」の表記方法。実線: 1対1、片側矢印: 1対多、両側矢印: 多対多。
- 注記: 属性名の実線の下線は主キー、破線の下線は外部キーを示す。主キーの実線が付いている属性名には、外部キーの破線を付けない。
データベース設計者である L主任は,“同一会員1枚限りの獲得制限”を制約として実装するために,図2の SQL文によってクーポン明細テーブルに対して,UNIQUE 制約を付けた。なお,予約サイトデータベースにおいては,UNIQUE 制約を構成する複数の列で一つの列でも NULL の場合は,UNIQUE 制約違反とならない。

図の説明テキスト
図2 “同一会員1枚限りの獲得制限”を制約とするためのSQL文
d クーポン明細 ADD CONSTRAINT クーポン明細_IX1
UNIQUE(クーポンコード, 獲得会員コード, 獲得制限_1枚限り)
L主任は,①予約テーブルの“クーポンコード”,“クーポン発行連番”に対しても,UNIQUE 制約を付けた。
予約サイトデータベースでは,更新目的の参照処理と更新処理においてレコード単位にロックを掛け,多重処理を行う設定としている。ロックが掛かるとトランザクションが終了するまでの間,他のトランザクションによる同一レコードに対する処理はロック解放待ちとなる。
〔クーポン獲得処理の連番管理方式〕
クーポン発行サービスと施設予約サービスの CRUD図(抜粋)を図3に示す。
クーポン新規登録処理では,1種類のクーポンにつき1レコードをクーポン管理テーブルに追加する。クーポン獲得チェック処理では,獲得可能期間,会員住所による獲得制限,発行上限枚数に関するチェックを行う。チェックの結果,エラーがない場合に表示される同意ボタンを押すことによって,クーポン獲得処理を行う。

図の説明テキスト
図3 クーポン発行サービスと施設予約サービスのCRUD図(抜粋)
| 処理名 | テーブル名 会員 | テーブル名 予約 | テーブル名 クーポン管理 | テーブル名 クーポン明細 | |
|---|---|---|---|---|---|
| クーポン発行サービス | クーポン新規登録 | - | - | C | - |
| クーポン発行サービス | クーポン獲得チェック | R | - | R | R |
| クーポン発行サービス | クーポン獲得 | R | - | ②R | ③CR |
| 施設予約サービス | 施設予約前チェック | R | R | R | R |
| 施設予約サービス | 施設予約実行 | R | C | - | R |
| 施設予約サービス | 施設予約キャンセル | R | RD | - | - |
注記 C: 追加, R: 参照, U: 更新, D: 削除
クーポン発行サービスでは,上限の定められた発行枚数分のクーポンを抜けや重複なく連番管理する方式が必要になる。特に,提携スポンサが都道府県,市区町村であるクーポンは割引金額が大きく,クーポンの発行直後にトラフィックが集中することが予想される。発行上限枚数到達後にクーポン獲得処理が動作する場合の考慮も必要である。L主任は,トラフィック集中時のリソース競合によるレスポンス悪化を懸念して,ロック解放待ちを発生させない連番管理方式(以下,ロックなし方式という)のSQL文(図4)を考案した。このSQL文では,ロックを掛けずに参照し,主キー制約によってクーポン発行連番の重複レコード作成を防止する。
ここで,関数 COALESCE(A, B) は,AがNULLでないときはAを,AがNULLのときはBを返す。また,“:クーポンコード”,“:会員コード”は,該当の値を格納する埋込み変数である。

図の説明テキスト
図4 ロックなし方式のSQL文
INSERT INTO クーポン明細 (クーポンコード, クーポン発行連番, 獲得会員コード, 獲得制限_1枚限り)
WITH 発行済枚数取得 AS (SELECT COALESCE(MAX(e), 0) AS 発行済枚数
FROM クーポン明細 WHERE クーポンコード = :クーポンコード)
SELECT :クーポンコード,
(SELECT 発行済枚数 + 1 FROM 発行済枚数取得 WHERE
(SELECT 発行済枚数 FROM 発行済枚数取得) < 発行上限枚数),
:会員コード, 獲得制限_1枚限り
FROM クーポン管理 WHERE クーポンコード = :クーポンコード
〔クーポン獲得処理の連番管理方式の見直し〕
ロックなし方式をレビューしたM課長は,トラフィック集中時に主キー制約違反が発生することによって,会員による再オペレーションが頻発するデメリットを指摘し,ロック解放待ちを発生させることによって更新が順次行われる連番管理方式(以下,ロックあり方式という)の検討と方式の比較,高負荷試験の実施を指示した。
L主任は,クーポン管理テーブルに対して初期値が0の“発行済枚数”という列を追加し,このデータ項目のカウントアップによって連番管理をするロックあり方式のSQL文(図5)を考案した。

図の説明テキスト
図5 ロックあり方式のSQL文
UPDATE クーポン管理 f
WHERE クーポンコード = :クーポンコード AND 発行済枚数 < g ;
INSERT INTO クーポン明細 (クーポンコード, クーポン発行連番, 獲得会員コード, 獲得制限_1枚限り)
SELECT :クーポンコード, 発行済枚数, :会員コード, 獲得制限_1枚限り
FROM クーポン管理 WHERE クーポンコード = :クーポンコード;
④ロックあり方式では,図3のCRUD図の一部に変更が発生する。
L主任は,ロックなし方式とロックあり方式の比較を表3にまとめ,高負荷試験を実施した。

図の説明テキスト
表3 ロックなし方式とロックあり方式の比較
| 方式 | ロック解放待ち | 主キー制約違反による再オペレーション | 発行上限枚数に到達後の動作 |
|---|---|---|---|
| ロックなし | 発生しない | 発生する | 副問合せで取得する発行済枚数+1の値がNULLになり,クーポン明細テーブルのクーポン発行連番がNULLのレコードを追加しようとして,主キー制約違反となる。 |
| ロックあり | 発生する | 発生しない | 更新が行われず,クーポン明細テーブルのクーポン発行連番が g のレコードを追加しようとして,主キー制約違反となる。 |
注記 表3中の g には,図5中の g と同じ字句が入る。
高負荷試験実施の結果,どちらの方式でも最大トラフィック発生時のレスポンス,スループットが規定値以内に収まることが確認できた。そこで,会員による再オペレーションの発生しないロックあり方式を採用することにした。
設問と解答・解説
設問1
〔クーポン発行サービスと施設予約サービスの E-R図〕について,(1)〜(3)に答えよ。
模範解答
施設コード,プランコード
採点基準
- 4点: 「施設コード」と「プランコード」の2つを1つずつ答えている。
- 2点: 「施設コード」または「プランコード」のどちらか1種類のみを答えている(同じ正解を二つ書いた場合を含む)。
- 0点: 「施設コード」と「プランコード」のいずれも答えていない(同じ誤答を二つ書いた場合を含む)。
解説
解説
図1(予約サイトデータベースのE-R図)を確認します。
「利用プラン」エンティティは主キーとして「施設コード」と「プランコード」を持っています。
また、「利用プラン」から「予約」へは1対多の関連(矢印)が引かれており、「予約」エンティティは「利用プラン」とのリレーションシップを構成するために外部キーを持つ必要があります。
図1の凡例「破線の下線は外部キーを示す」に従い、「予約」エンティティの空欄 a・b には「利用プラン」の主キーである「施設コード」と「プランコード」が外部キーとして入ります(順不同)。
高得点のポイント
- 図1のE-R図からエンティティ間のリレーションシップを正しく読み取ること。
- 外部キーとして必要な親エンティティの主キー(「施設コード」「プランコード」)を正確に抽出できること。
なお、採点基準は、正解の2つを1つずつ答えている場合は満点、正解のうち1種類だけを答えている場合(同じ正解を二つ書いた場合を含む)は半分、正解を1つも答えていない場合(同じ誤答を二つ書いた場合を含む)は0点となります。
図1中の c に入れる適切なエンティティ間の関連及び属性名を答えよ。
なお,エンティティ間の関連及び属性名の表記は,図1の凡例及び注記に従うこと。
模範解答
↑
採点基準
- 2点: 「↑」と正しく解答している。
- 0点: 正解の記号以外を解答している、または未解答。
解説
【問題の本文・図表】の図1において、「利用プラン」と「施設」の間の関連を考えます。
「施設」の主キーは 施設コード であり、「利用プラン」はこれを外部キーとして保持しています。つまり、1つの「施設」に対して複数の「利用プラン」が存在するという「1対多」の関係が成立します。
凡例の「1対多」の記号(片側矢印)に従うと、「施設」(1)から「利用プラン」(多)に向かって矢印を引くことになります。
図の配置では「施設」が下、「利用プラン」が上にあるため、c には上向きの矢印( ↑ )が入ります。
高得点のポイント
- 主キーと外部キーの関係から「1対多」の方向を正確に判定できているか。
- 図表上の配置に従って適切な矢印記号を選択できているか。
図2中の d に入れる適切な字句を答えよ。
模範解答
ALTER TABLE
採点基準
- 2点: 「ALTER TABLE」と正しく解答している(大文字小文字は問わない)。
- 1点: 解答の意図は合っているが、余分な文字が含まれている等、完全に正確ではない。
- 0点: 正解の要件を満たしていない、または未解答。
解説
図2のSQL文は、既存の「クーポン明細」テーブルに対して新たに UNIQUE 制約(クーポン明細_IX1)を追加する処理です。
関係データベースにおいて、テーブルの定義を変更・追加するためにはデータ定義言語(DDL)の ALTER TABLE 構文を使用します。
したがって、d には ALTER TABLE が入ります。
高得点のポイント
- テーブルに対する制約追加の際に必要なSQL(DDL)の基本構文を正しく記述できているか。
本文中の下線①は,どのような業務要件を実現するために行ったものか。30字以内で述べよ。
模範解答
1枚のクーポンは一つの予約だけに利用できる。
採点基準
- 2点: 本文から「1枚のクーポンは一つの予約だけに利用できる。」を過不足なく抜き出している。
- 1点: 業務要件の意図は合っているが、本文の正確な抜き出しになっていない、または余分な文字が含まれている。
- 0点: 題意に沿った抜き出しになっていない、または未解答。
解説
下線①で「予約」テーブルの「クーポンコード」と「クーポン発行連番」の組に対してUNIQUE制約を付与した理由を問う問題です。
表2「クーポン発行サービスの概要」の「クーポンの利用」の項を確認すると、「1枚のクーポンは一つの予約だけに利用できる。」という業務要件が記載されています。
「クーポンコード」と「クーポン発行連番」の組み合わせは、発行された個別の1枚のクーポンを一意に識別するものです。
この組み合わせに対して予約テーブル上でUNIQUE制約を付与することで、同一のクーポンが複数の予約レコードに登録されること(二重利用)を防ぎ、前述の業務要件をデータベースの制約として確実に実現しています。
高得点のポイント
- 表2の業務要件の中から、該当の制約に直接対応する文章を過不足なく抜き出せているか。
設問1(2)のdは,正答率が低かった。ALTER TABLE文は,制約の追加,削除のほか,列の追加,変更などにも使われるSQL(DDL)であり,覚えておいてほしい。設問1(3)は,正答率が平均的であった。制約を付けたテーブルに関連する業務要件,UNIQUE制約違反となるデータの組合せを不可とする業務要件については,正しく読み取れているようであった。
設問2
図4中の e に入れる適切な字句を答えよ。
模範解答
クーポン発行連番
採点基準
- 2点: 「クーポン発行連番」と正しく解答している。
- 1点: 解答の意図は合っているが、列名が不正確など一部誤りがある。
- 0点: 正解の要件を満たしていない、または未解答。
解説
図4のロックなし方式のSQL文における副問合せ 発行済枚数取得 の内容を読み解きます。
目的は、現在クーポン明細テーブルに登録されている当該クーポンの「発行済枚数」を取得することです。
発行済枚数は、これまで1から順に連番で発行されたクーポンの「最大値」と等しくなります。したがって、MAX() 関数の中には、連番を管理している列である クーポン発行連番 を指定するのが適切です。
これにより、現在の最大の連番を取得し、次に発行するクーポンの連番(+1)を計算しています。
高得点のポイント
- 連番管理の仕組みを理解し、最大値を取得すべき列名(「クーポン発行連番」)を正しく解答できているか。
設問3
図5中の f に入れる適切な字句を答えよ。
模範解答
SET 発行済枚数 = 発行済枚数 + 1
採点基準
- 2点: 「SET 発行済枚数 = 発行済枚数 + 1」と正しく解答している。
- 1点: 意図は合っているが、SQLの構文として不完全、または余分な文字が含まれている。
- 0点: 正解の要件を満たしていない、または未解答。
解説
図5のロックあり方式のSQL文におけるUPDATE文の構文を完成させる問題です。
この方式では、新たに設けたクーポン管理テーブルの「発行済枚数」列をカウントアップすることで連番管理を行います。
UPDATE文で列の値を更新する際は SET 句を用います。
発行済枚数を1つ増やす処理であるため、f には SET 発行済枚数 = 発行済枚数 + 1 が入ります。
高得点のポイント
- UPDATE文におけるSET句を用いたカウントアップの構文を正しく記述できているか。
図5中の g に入れる適切な字句を答えよ。
模範解答
発行上限枚数
採点基準
- 2点: 「発行上限枚数」と正しく解答している。
- 1点: 意図は合っているが、列名が不正確など一部誤りがある。
- 0点: 正解の要件を満たしていない、または未解答。
解説
図5のUPDATE文におけるWHERE句の条件 発行済枚数 < g を考えます。
クーポンの獲得処理は、あらかじめ定められた上限枚数に達するまで行われます。上限に到達した後はカウントアップ(UPDATE)を行わないように制御する必要があります。
図1のE-R図でクーポン管理テーブルの属性を確認すると、上限を定義する列として 発行上限枚数 が存在します。
したがって、現在の発行済枚数がこの上限を下回っている場合のみ更新を許可するため、g にはこの列名が入ります。
高得点のポイント
- テーブルの列定義から、上限枚数を表す正確な列名を読み取れているか。
設問3のfは,正答率が低かった。UPDATE文は,連番のカウントアップをはじめ,表の更新に使われるSQLであり,SET句の構文と併せて覚えておいてほしい。
設問4
模範解答
RU
採点基準
- 2点: 「RU」または「UR」と正しく解答している。
- 1点: 「R」または「U」のみ解答しているなど、部分的に正しい。
- 0点: 正解の要件を満たしていない、または未解答。
解説
図3のCRUD図における「クーポン獲得」処理の「クーポン管理」テーブルに対するレコード操作(②)の変更を問う問題です。
変更前(ロックなし方式)では、図4のSQL文のとおり「クーポン管理」テーブルに対する操作はSELECTのみであり、「R(参照)」となっていました。
一方、変更後(ロックあり方式)では、図5のSQL文で示されているように、「クーポン管理」テーブルに対して UPDATE による更新が行われ、さらに INSERT 文内の SELECT 句で参照も行われます。
したがって、更新(U)と参照(R)の両方が発生するため、操作内容は RU となります。
高得点のポイント
- 図5のSQL文から、「クーポン管理」テーブルに対して「参照(R)」と「更新(U)」の両方が行われていることを正確に把握できているか。
模範解答
C
採点基準
- 2点: 「C」と正しく解答している。
- 0点: 正解の記号以外を解答している、または未解答。
解説
図3のCRUD図における「クーポン獲得」処理の「クーポン明細」テーブルに対するレコード操作(③)の変更を問う問題です。
変更前(ロックなし方式)では、図4のSQL文において「クーポン明細」テーブルから現在の最大連番を取得するための SELECT(R)と、新たなクーポンを登録するための INSERT(C)が行われており、「CR」となっていました。
一方、変更後(ロックあり方式)では、図5のSQL文を見ると、「クーポン明細」テーブルに対する操作は INSERT(C)のみであり、SELECT による参照は行われていません(連番はクーポン管理テーブルから取得しています)。
したがって、操作内容は C となります。
高得点のポイント
- 図5のSQL文から、「クーポン明細」テーブルに対しては「追加(C)」のみが行われていることを正確に把握できているか。