仮の宿 学習室

応用情報技術者 APPLIED IT ENGINEER

ソフトウェアとデータベース

講義 5 本・確認問題 50 問 | 本試験では「テクノロジ系」(50問)の一部 | 最終更新 2026-09-24

この章で学ぶこと
目次
  1. OSの役割とプロセス管理
  2. 仮想記憶とファイルシステム
  3. データベース設計と関係代数
  4. SQLとインデックス
  5. トランザクションと障害回復
  6. 確認問題(50問)
  7. 演習ツール

1. OSの役割とプロセス管理

OSがCPUをどう配り、プロセスとスレッドをどう動かし、デッドロックをどう避けるのかが分かります。

オペレーティングシステム(OS)は、CPU・主記憶・入出力装置・ファイルといった資源を、複数のプログラムが安全に共同利用できるように仲立ちするソフトウェアです。中核であるカーネルは特権命令を実行できるカーネルモードで動き、応用プログラムは特権命令を実行できないユーザモードで動きます。応用プログラムがファイル入出力やメモリ確保のように特権を要する処理をしたいときは、システムコールでカーネルに依頼します。この分離があるおかげで、あるプログラムの暴走が他のプログラムやOS自身を壊さずに済みます。ハードウェアからの通知は割込みとして届き、OSは実行中の処理をいったん退避して割込み処理ルーチンへ切り替えます。

実行中のプログラムをプロセスといい、OSはプロセスごとに独立したアドレス空間と、プロセス制御ブロック(PCB)という管理情報を持たせます。PCBにはプログラムカウンタやレジスタの内容、優先度、割り当てた資源、状態などが入っていて、CPUを別のプロセスに渡すときはこれを退避し、戻すときに復元します。この入替えがコンテキストスイッチで、それ自体は仕事を進めないオーバヘッドなので、起こる回数が多すぎると全体の効率が落ちます。

スレッドはプロセスの中にある実行の流れです。同じプロセスのスレッドどうしはアドレス空間とファイル記述子を共有し、スタックとレジスタだけを別々に持ちます。共有しているぶん生成も切替えも軽く、データの受渡しに通信の仕組みが要りません。その代わり、一つのスレッドが不正なメモリ操作をするとプロセス全体が巻き添えになり、共有データの読み書きが重なると結果が実行順に左右される競合状態が起きます。独立性を優先するならプロセス、軽さと共有のしやすさを優先するならスレッド、という判断になります。

プロセスは実行可能・実行・待ちの三つの状態を行き来します。CPUを割り当てられると実行可能から実行へ、入出力を要求すると実行から待ちへ、入出力が終わると待ちから実行可能へ移ります。実行から実行可能へ戻るのは、時間切れや、より優先度の高いプロセスに横取りされたときで、これをプリエンプションといいます。待ちから直接実行へ移る遷移はありません。いったん実行可能の列に並び直すからです。

どのプロセスに次のCPUを渡すかを決めるのがスケジューリングです。到着順(FCFS)は単純ですが、長い処理が先頭にいると後続が待たされます。処理時間の短い順(SJF)は平均ターンアラウンドタイムを最小にできますが、実行前に処理時間が分かる前提が要り、長い処理が後回しにされ続ける飢餓が起こり得ます。ラウンドロビンは一定のタイムクォンタムごとに順番に回すので応答時間が安定し、対話処理に向きます。タイムクォンタムを短くすると応答は良くなる一方でコンテキストスイッチの回数が増え、長くすると到着順に近づきます。評価の物差しは、ターンアラウンドタイム(完了時刻から到着時刻を引いた値)、待ち時間、応答時間、単位時間当たりの処理件数であるスループットです。

複数のプロセスが同じ資源を同時に書き換えないようにするのが排他制御です。同時に一つしか入れない区間をクリティカルセクションといい、セマフォやミューテックス、モニタで守ります。セマフォは使える資源の個数を表す変数で、取るときのP操作、返すときのV操作を必ず対にします。初期値1のセマフォは、実質ミューテックスとして働きます。

排他制御を雑に組むとデッドロックになります。デッドロックが成立するには、相互排除・保持と待ち・横取り不可・循環待ちの四つがすべて必要で、どれか一つを崩せば起きません。資源に番号を付けて必ず小さい順に確保させる(循環待ちを崩す)、必要な資源を最初にまとめて確保させる(保持と待ちを崩す)といった予防が代表です。銀行家アルゴリズムは、要求を受け入れても安全な状態が保てるかを毎回判定する回避の手法です。実務では検出と回復、つまり一定時間ごとに待ちグラフの循環を調べ、いずれかのプロセスを強制終了して巻き戻す方式も広く使われます。なお、n個のプロセスがそれぞれ同種の資源を最大k個まで要求するとき、資源が n×(k-1)+1 個あればデッドロックは絶対に起きません。全員があと1個で足りる状態まで配っても1個余るからです。

主なスケジューリング方式と、それを選ぶ理由
方式次に走らせるもの向いている場面弱点
到着順(FCFS)先に到着したものバッチ処理で公平さだけ確保したいとき長い処理が先頭にいると後続が待たされる
処理時間順(SJF)残り処理時間が最も短いもの平均ターンアラウンドタイムを縮めたいとき処理時間の見積りが要る。長い処理が飢餓になる
優先度順優先度が最も高いもの応答が命の処理を先に通したいとき低優先度が飢餓になる。エージングで補う
ラウンドロビン順番待ちの先頭を一定時間だけ対話処理。応答時間をそろえたいときクォンタムが短いと切替えのオーバヘッドが増える
多段フィードバック上位の待ち行列から。使い切ると下位へ処理時間が事前に分からない混在環境設計が複雑で、調整項目が多い
大域: 整数型: s ← 1   /* 使える資源の数。1 ならミューテックス */ ○P(整数型: s)   /* 資源を取る */  while (s ≦ 0)    /* 空くまで待つ */  endwhile  s ← s - 1 ○V(整数型: s)   /* 資源を返す */  s ← s + 1

用語

カーネルモード
特権命令を実行できる動作モード。OSの中核はここで動き、応用プログラムはユーザモードで動いてシステムコール経由でカーネルに処理を依頼する。
システムコール
応用プログラムがOSの機能を呼び出すための入口。ファイル入出力やメモリ確保など、特権が要る処理はすべてこれを通る。
プロセス制御ブロック
PCB。プロセスごとの管理情報で、プログラムカウンタ、レジスタの内容、優先度、状態、割当て資源などを保持する。コンテキストスイッチでの退避と復元の対象。
コンテキストスイッチ
CPUを使うプロセスやスレッドを切り替える処理。レジスタなどの退避と復元が必要で、それ自体は仕事を進めないオーバヘッドになる。
スレッド
プロセス内の実行の流れ。同じプロセスのスレッドはアドレス空間とファイル記述子を共有し、スタックとレジスタだけを個別に持つ。切替えは軽いが独立性は低い。
プリエンプション
実行中のプロセスからCPUを強制的に取り上げること。時間切れや高優先度プロセスの到着で起こり、実行状態から実行可能状態へ戻る。
ターンアラウンドタイム
処理を依頼してから結果がすべて得られるまでの時間。完了時刻から到着時刻を引いた値で、待ち時間と処理時間の合計に等しい。
ラウンドロビン
一定のタイムクォンタムごとにCPUを順番に回すスケジューリング。応答時間が安定するので対話処理に向く。クォンタムを短くすると切替え回数が増える。
セマフォ
使える資源の個数を表す変数と、取得のP操作・解放のV操作の組で排他制御を行う仕組み。初期値1ならミューテックスと同じ働きになる。
競合状態
複数の実行の流れが同じデータを読み書きし、実行の順序によって結果が変わってしまう状態。クリティカルセクションを排他制御で守って防ぐ。
デッドロックの4条件
相互排除、保持と待ち、横取り不可、循環待ち。四つすべてがそろったときだけデッドロックが成立するので、一つを崩せば予防できる。
銀行家アルゴリズム
資源要求を受け入れても全プロセスが完了できる安全な状態が保てるかを毎回判定し、危険なら要求を待たせるデッドロック回避の手法。最大要求量を事前に申告させる必要がある。

例題

例題:例題:時刻0に3件の処理A(6 ms)、B(2 ms)、C(4 ms)が同時に到着した。到着順(A・B・Cの順)と処理時間順(SJF)で、平均ターンアラウンドタイムはそれぞれいくらか。
答えと考え方 到着順では完了時刻が6・8・12 msなので、平均は 26/3 で約8.7 ms。SJFではB・C・Aの順に走って完了時刻が2・6・12 msとなり、平均は 20/3 で約6.7 ms。処理の総量は同じでも、短いものを先に通すほど平均の待ちが減るのがSJFの効き目です。
例題:例題:3個のプロセスが同種の資源をそれぞれ最大3個まで要求する。デッドロックが絶対に起きないためには資源が何個あればよいか。
答えと考え方 各プロセスに「あと1個で完了」という状態まで配ると 3×(3-1)=6 個を使い切る。ここに1個でも余分があれば、どれか1個が完了して資源を返し、連鎖的に全員が完了できる。よって 3×(3-1)+1=7 個。一般に n×(k-1)+1 個です。

出典・根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

2. 仮想記憶とファイルシステム

ページングでメモリをどう見せかけているか、どのページを追い出すか、ファイルとミドルウェアの役割までを押さえます。

主記憶は有限なので、OSは実際の容量より広いアドレス空間をプログラムに見せます。これが仮想記憶です。仮想アドレス空間を固定長のページに、実記憶を同じ大きさのページフレームに区切り、どの仮想ページがどのページフレームにあるかをページテーブルで対応付けます。必要になった時点でページを読み込むデマンドページングが一般的で、参照したページが実記憶に無ければページフォールトという割込みが起き、OSが補助記憶から読み込みます。

アドレス変換の考え方は単純です。仮想アドレスの下位はページ内オフセット、上位はページ番号です。ページの大きさが 2ⁿ バイトなら下位nビットがオフセットで、残りがページ番号になります。たとえば仮想アドレスが32ビットでページが4Kバイト(2¹² バイト)なら、オフセットは12ビット、ページ番号は20ビットで、1プロセスあたり 2²⁰ 個のページが並ぶことになります。ページテーブルを毎回主記憶から読むと遅いので、直近の変換結果だけを覚えておく専用の連想記憶TLBを置き、ここに当たれば1回のメモリアクセスで済ませます。

実記憶がいっぱいのときは、どのページを追い出すかを決めなければなりません。FIFOは読み込んだ順に追い出す方式で実装は軽い反面、よく使うページも順番が来れば追い出します。LRUは最後に参照されてから最も時間がたったものを追い出す方式で、参照の局所性に合うので命中率が高くなりますが、参照時刻の記録にコストがかかります。LFUは参照回数が最も少ないものを追い出します。実装の折衷案として、参照ビットを一周ずつ見て回るクロック方式がよく使われます。FIFOには、ページフレームを増やしたのにページフォールトが増える場合があるという不思議な現象があり、これをベラディの異状といいます。LRUでは起こりません。

多重度を上げすぎると、どのプロセスも自分のページをそろえられず、ページの追い出しと読み込みだけでCPU時間が消えていきます。この状態がスラッシングです。あるプロセスが直近に参照したページの集合をワーキングセットといい、これが実記憶に載るだけのページフレームを確保できるように多重度を下げるのが対策になります。ページを大きくするとページテーブルは小さくなり1回の入出力で運べる量も増えますが、使わない部分まで読み込むぶん無駄が増え、ページ内の断片化も大きくなります。逆に小さくすると無駄は減りますが、ページテーブルが膨らみページフォールトの回数が増えます。

ファイルシステムは、補助記憶上のブロックの集まりを、名前でたどれるファイルとディレクトリに見せる仕組みです。UNIX系ではファイルの実体情報を i ノードに持たせ、所有者・権限・更新時刻と、データブロックの位置を記録します。ディレクトリは名前と i ノード番号の対応表にすぎないので、同じ実体に複数の名前を付けるハードリンクが作れます。書込みの途中で電源が落ちても構造が壊れないように、変更内容をあらかじめログに書いてから反映するのがジャーナリングファイルシステムです。ファイルの追加と削除を繰り返すと空き領域が細切れになるので、断片化の解消や、世代管理を伴うバックアップの設計も運用上の論点になります。

OSと応用プログラムの間に入り、多くの業務で共通して必要になる機能を引き受けるソフトウェアがミドルウェアです。データベース管理システム、トランザクションの実行と資源の割当てを管理するTPモニタ、画面と業務ロジックを動かすWebアプリケーションサーバ、非同期のメッセージ交換を仲介するメッセージキュー、運用管理ツールなどが該当します。近年は、OSのカーネルを共有したまま実行環境を分離するコンテナが標準的な配置単位になり、仮想マシンよりも起動が速く密度を上げやすい一方、カーネルを共有するぶん分離の強さでは仮想マシンに劣る、という選択の判断が加わりました。

ページサイズを大きくしたときに何が起きるか
観点ページを大きくするとページを小さくすると
ページテーブルの大きさエントリ数が減って小さくなるエントリ数が増えて大きくなる
1回の入出力の効率まとめて運べるので良くなる細かい入出力が増えて悪くなる
ページ内の無駄(内部断片化)使わない部分まで載るので増える減る
ページフォールトの回数先読み効果で減りやすい増えやすい
実記憶に載るプログラムの数1本あたりが重くなり減りやすい増やしやすい

用語

デマンドページング
プログラム全体を先に読み込まず、参照されたページだけをその都度読み込む方式。参照されないページは読み込まれないので、実記憶を節約できる。
ページフォールト
参照した仮想ページが実記憶に無いときに発生する割込み。OSが補助記憶からページを読み込み、必要なら別のページを追い出す。処理時間はミリ秒単位で非常に重い。
TLB
アドレス変換の直近の結果を保持する専用の連想記憶。ここに当たればページテーブルを読みに行かずに済むので、仮想記憶のアクセス時間を実用的な水準に保てる。
ページテーブル
仮想ページ番号と実記憶のページフレーム番号の対応表。有効ビットや参照ビット、変更ビットも持つ。ページ数が多いと多段構成にして節約する。
LRU
最後に参照されてから最も時間がたったページを追い出す置換方式。参照の局所性に合うので命中率は高いが、参照時刻の記録にコストがかかる。
ベラディの異状
ページフレームを増やしたのにページフォールトが増えてしまう現象。FIFOで起こり得るが、LRUのようなスタックアルゴリズムでは起こらない。
スラッシング
多重度を上げすぎてページの追い出しと読み込みばかりが起こり、実際の処理が進まなくなる状態。多重度を下げるのが基本的な対策。
ワーキングセット
あるプロセスが直近の一定期間に参照したページの集合。これが実記憶に載るだけのページフレームを確保できればスラッシングを避けられる。
iノード
UNIX系ファイルシステムでファイルの実体情報を持つ管理領域。所有者、権限、更新時刻、データブロックの位置を記録する。ファイル名は含まない。
ジャーナリング
ファイルシステムへの変更内容を先にログへ記録してから本体に反映する方式。障害後はログを見るだけで整合性を回復でき、全体検査が不要になる。
ミドルウェア
OSと応用プログラムの間で共通機能を担うソフトウェア。DBMS、TPモニタ、Webアプリケーションサーバ、メッセージキューなどが該当する。
コンテナ
OSのカーネルを共有したまま、ファイルシステムやプロセス空間を分離して実行環境を作る方式。仮想マシンより軽く起動が速いが、分離の強さは仮想マシンに劣る。

例題

例題:例題:ページ参照列が 1, 2, 3, 4, 2, 1, 5, 2, 1, 3 のとき、ページフレーム3個でFIFOとLRUのページフォールトはそれぞれ何回か。
答えと考え方 FIFOは8回、LRUは7回。FIFOは4を読み込む時点で最古の1を追い出すため、直後に再び参照される1でまたフォールトします。LRUは直近に使われたものを残すので、この列では1回ぶん得をします。最初の3回は空のフレームを埋めるフォールトなので、どちらの方式でも必ず数えます。
例題:例題:仮想アドレスが24ビット、ページの大きさが2Kバイトのとき、ページ番号は何ビットか。
答えと考え方 2Kバイトは 2¹¹ バイトなので、オフセットは11ビット。残りの 24-11=13 ビットがページ番号で、1プロセスあたり 2¹³ 個のページを持てます。ページの大きさを4Kバイトにすればオフセットは12ビット、ページ番号は12ビットになります。

出典・根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

3. データベース設計と関係代数

E-R図から表を起こし、正規化でどこまで分解し、どこで止めるかを判断できるようになります。

データベース設計は、現実の業務を写し取る概念設計、それを関係モデルの表に落とす論理設計、性能と容量を詰める物理設計の順に進みます。概念設計の道具がE-R図で、管理したいものを実体、実体どうしのつながりを関連として描き、関連には1対1・1対多・多対多という多重度を付けます。存在するために親の実体が必要なもの(受注に対する受注明細など)は弱実体と呼ばれ、親の主キーを含む複合キーで識別します。関係データベースの表には多対多をそのまま書けないので、両側の主キーの組を持つ連関エンティティを間に置き、1対多を二つに分けて実装します。

論理設計の中心が正規化です。手掛かりになるのが関数従属で、Xの値が決まればYの値が一つに定まる関係を X→Y と書き、Xを決定項といいます。1行の中に繰返しがある非正規形から、どのます目にも値が一つだけ入る第1正規形へ。複合主キーの一部だけで決まる項目、つまり部分関数従属を別表へ出して第2正規形へ。主キー以外の項目を経由して決まる推移的関数従属を別表へ出して第3正規形へ、と段階的に分解します。第3正規形まで進めると、同じ事実が1か所にしか書かれない状態に近づき、更新のたびに矛盾が生じる更新時異状を防げます。

第3正規形でも残る不都合を取り除いたものがボイスコッド正規形(BCNF)です。BCNFは「すべての関数従属について、決定項が候補キーである」状態を指します。候補キーが複数あり、それらが項目を共有しているときに第3正規形との差が出ます。たとえば(会員, プラン, 担当者)という表で、1人の担当者は1つのプランだけを受け持ち、会員とプランの組で担当者が決まるなら、候補キーは{会員, プラン}と{会員, 担当者}の二つです。担当者→プランという従属の決定項である担当者は候補キー全体ではないのでBCNFを満たしません。ここを分解すると更新時異状は消えますが、教員が担当する科目を1件も持たない状態を表現できるようになるなど、元の制約が失われることもあり、常に分解が正解とは限りません。

正規化は目的ではなく手段です。分解すると表の数が増え、参照のたびに結合が必要になるので、読み取りが圧倒的に多い集計画面や、履歴として当時の値を凍結して残したい伝票明細では、あえて重複を持たせる非正規化を選ぶことがあります。受注明細に商品名と単価を写して持たせる、月次の合計金額を集計列として持たせる、といった判断です。ただし非正規化は更新時異状のリスクを引き受ける決断なので、更新経路を1本に絞る、集計はトリガやバッチで必ず作り直す、といった歯止めとセットにします。「まず第3正規形まで作り、実測して遅い部分だけ戻す」が実務の定石です。

整合性はキーと制約で守ります。行を一意に識別でき、どの項目を欠いても識別できなくなる項目の組が候補キーで、その一つを主キーに選びます。主キーには重複も空値も入れられません(実体整合性制約)。他の表の主キーを指す項目が外部キーで、その値は参照先に実在するかNULLでなければなりません(参照整合性制約)。親の行を消そうとしたときの動きは、拒否するRESTRICT、子も一緒に消すCASCADE、子の外部キーをNULLにするSET NULLから選びます。何を選ぶかは業務の意味で決めるもので、伝票の親を消したら明細も消えてよいのか、そもそも消させないのかを設計時に決めておきます。

関係データベースの問合せの土台が関係代数です。行を絞る選択、列を取り出す射影、共通の列で行をつなぐ結合、すべての組合せを作る直積、集合演算の和・差・積、そして「Sのすべての値と対応があるものだけを取り出す」商があります。商は「すべての科目を履修した学生」のような全称の条件を表し、SQLでは二重のNOT EXISTSで書くのが定番です。関係代数は結果もまた関係になるので、演算を積み重ねられます。SQLの一文は、この演算の組合せを宣言的に書いたものだと考えると読みやすくなります。

関係代数の演算と、SQLでの書き方の対応
演算何をするかSQLでの書き方結果の行数の目安
選択条件に合う行だけを残すWHERE 句元の行数以下
射影指定した列だけを取り出すSELECT の列指定(重複はDISTINCT)元の行数以下
直積両方の関係の全組合せを作るFROM に2表を並べる(結合条件なし)m×n 行
結合共通の列の値が一致する行をつなぐINNER JOIN ... ON0 から m×n 行の間
和・差・積同じ列構成の関係どうしの集合演算UNION/EXCEPT/INTERSECT重複は取り除かれる
商Sのすべての行と対応する値だけを残すNOT EXISTS を二重に入れ子元の値の種類数以下
部分関数従属を別表に出すと、講座名は1か所だけになる
/* 第2正規形どまりの受講表。主キーは (社員番号, 講座コード) */CREATE TABLE 受講 (社員番号 TEXT, 講座コード TEXT,                   講座名 TEXT NOT NULL, 講師名 TEXT NOT NULL,                   受講日 TEXT NOT NULL,                   PRIMARY KEY (社員番号, 講座コード));/* 講座コード -> 講座名, 講師名 は主キーの一部だけで決まる(部分関数従属)*/ /* 第3正規形へ分解した形 */CREATE TABLE 講座 (講座コード TEXT PRIMARY KEY,                   講座名 TEXT NOT NULL, 講師名 TEXT NOT NULL);CREATE TABLE 受講2 (社員番号 TEXT, 講座コード TEXT NOT NULL                      REFERENCES 講座(講座コード),                    受講日 TEXT NOT NULL,                    PRIMARY KEY (社員番号, 講座コード)); INSERT INTO 講座 VALUES ('C1','SQL入門','青山'),                        ('C2','統計の基礎','蒼井');INSERT INTO 受講2 VALUES ('E001','C1','2026-04-10'),                         ('E002','C1','2026-04-10'),                         ('E001','C2','2026-05-12'); /* 分解しても、結合すれば元の見え方に戻せる */SELECT 受講2.社員番号, 講座.講座名, 講座.講師名, 受講2.受講日  FROM 受講2 JOIN 講座 ON 受講2.講座コード = 講座.講座コード;

用語

弱実体
単独では識別できず、親の実体があって初めて存在できる実体。受注に対する受注明細など。親の主キーを含む複合キーで識別する。
連関エンティティ
多対多の関連を表に落とすために、双方の主キーの組を主キーとして持たせた中間の表。学生と講義の間に置く履修表が典型例。
関数従属
Xの値が決まればYの値が一つに定まる関係。X→Yと書き、Xを決定項という。正規化はこの従属を手掛かりに表を分解する作業である。
部分関数従属
複合主キーの一部だけで決まってしまう関数従属。これを別表に出すと第2正規形になる。単一項目が主キーの表には存在しない。
推移的関数従属
主キー→A→Bのように、主キー以外の項目を経由して決まる関数従属。これを別表に出すと第3正規形になる。
ボイスコッド正規形
すべての関数従属の決定項が候補キーである状態。候補キーが複数あって項目を共有するときに第3正規形との差が出る。分解で関数従属が保存されないことがある。
更新時異状
同じ事実が複数箇所に重複して格納されているために、一部だけを更新すると矛盾が生じる状態。挿入・更新・削除のそれぞれで起こり得る。
非正規化
読み取り性能や履歴の凍結を目的に、あえて重複を持たせて表を戻す設計判断。更新時異状のリスクを引き受けるので、更新経路の限定などの歯止めが要る。
候補キー
行を一意に識別でき、かつどの項目を欠いても識別できなくなる項目の組。一つの表に複数存在し得る。その一つを主キーに選ぶ。
参照動作
参照されている親の行を削除・更新したときの子の扱い。拒否するRESTRICT、連鎖するCASCADE、NULLにするSET NULLなどを業務の意味で選ぶ。
関係代数の商
関係Rを関係Sで割り、Sのすべての行と対応を持つ値だけを取り出す演算。「すべての科目を履修した学生」のような全称条件を表す。
射影
関係から指定した列だけを取り出す演算。重複した行はまとめられる。行を絞る選択と対になる基本演算である。

例題

例題:例題:受講(社員番号, 講座コード, 講座名, 講師名, 受講日)という表があり、主キーは(社員番号, 講座コード)である。講座名と講師名は講座コードで決まる。この表は第何正規形で、どこが問題か。
答えと考え方 講座名と講師名は主キーの一部である講座コードだけで決まるので、部分関数従属があります。よって第1正規形どまりで、第2正規形を満たしていません。同じ講座を複数人が受ければ講座名と講師名が行の数だけ書き写され、講師が交代したときに1行だけ直すと表の中で食い違います。講座(講座コード, 講座名, 講師名)を切り出して受講側に講座コードだけを残せば、部分関数従属が消えて第2正規形になります。
例題:例題:4行の関係Rと3行の関係S(列構成は同じ)があり、共通の行が1行ある。直積・和・差(R-S)の行数はそれぞれいくつか。
答えと考え方 直積は行どうしの全組合せなので 4×3 で12行。和は重複を1行にまとめるので 4+3-1 で6行。差はRにあってSにない行なので 4-1 で3行です。列構成が同じでないと和や差は取れず、直積だけが列構成の異なる関係でも作れます。

出典・根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

4. SQLとインデックス

結合・副問合せ・集約・ウィンドウ関数の読み方と、索引を張るかどうかの判断ができるようになります。

SQLは「どう取るか」ではなく「何がほしいか」を書く言語ですが、結果を正しく読むには評価の順番を知っておく必要があります。FROMで対象の表を決め、WHEREで行を絞り、GROUP BYでまとめ、HAVINGでグループを絞り、SELECTで列を作り、ORDER BYで並べます。WHEREは1行ずつを見るので集約関数を書けず、HAVINGはまとまったグループを見るので集約関数を書けます。SELECTで付けた別名をWHEREで使えないのに、ORDER BYでは使えるのも、この順番から説明できます。

複数の表をつなぐのが結合です。内部結合は両方に相手がいる行だけを残します。左外部結合は左に書いた表の行をすべて残し、相手のいない行は右側の列がNULLになります。「社員が1人もいない部門も一覧に出したい」なら外部結合が必要で、ここで内部結合を使うとその部門が消えます。さらに、外部結合の結果に COUNT(*) を使うと相手がいない行も1と数えてしまうので、人数を数えるときは COUNT(社員番号) のように相手側の列を数えます。同じ表を役割違いで2度使う自己結合は、社員と上司のような同一表内の親子関係をたどるときに使います。

問合せの中に問合せを入れるのが副問合せです。外側と無関係に1度だけ評価される非相関副問合せと、外側の行ごとに評価し直される相関副問合せがあります。「自分の部門の平均給与より高い社員」は相関副問合せの典型です。ここで気を付けたいのがNULLです。IN や NOT IN の副問合せ結果にNULLが1件でも混じると、NOT IN は決して真になりません。NULLとの比較結果が真でも偽でもない不定になるからです。「社員が1人もいない部門」を NOT IN で書くと、部門コードがNULLの社員が1人いるだけで結果が0件になります。この用途では NOT EXISTS を使うのが安全です。

集約関数もNULLの扱いが要点です。COUNT(*) は行そのものを数えるのでどの列がNULLでも1と数えますが、COUNT(列名) はその列がNULLの行を数えません。SUM・AVG・MAX・MINもNULLを無視するので、AVGはNULLを0とみなした平均ではなく、NULLを除いた件数で割った平均になります。グループが一つも作られなければ COUNT は0を返しますが、SUMはNULLを返す点も実務では引っかかりやすいところです。

行をまとめずに、行ごとの値と集計を同時に出したいときに使うのがウィンドウ関数です。OVER 句で対象の範囲を指定し、PARTITION BY でグループを分け、ORDER BY で並べます。順位を付ける三つの関数は挙動が違います。同点があるとき、RANK は同順位のあとを飛ばし(1, 2, 2, 4)、DENSE_RANK は飛ばさず(1, 2, 2, 3)、ROW_NUMBER は同点でも必ず異なる番号を振ります(1, 2, 3, 4)。GROUP BY と違って行が消えないので、明細と順位を並べた一覧が1文で書けます。

ビューは問合せに名前を付けたもので、実体は持ちません。よく使う結合や絞り込みを隠して読みやすくする、列や行を限定して見せることでアクセス制御に使う、といった目的があります。集約や DISTINCT を含むビューは、どの元の行を直せばよいか決まらないので更新できません。索引(インデックス)は列の値から行の位置を引ける別の構造で、多くはB木の一種です。等価条件や範囲条件、ORDER BY の並べ替えを速くしますが、更新のたびに索引側も直すので、更新が多い列に索引を増やすと逆に遅くなります。また、条件に合う行が表全体の何割にもなるような選択率の高い条件では、索引をたどって1行ずつ取りに行くより表を頭から読むほうが速く、実行計画も全表走査を選びます。複合索引は先頭の列から順に使われるので、(部門コード, 入社年)の索引は部門コード単独の検索には効きますが、入社年だけの検索には効きません。

索引が効く場面と効かない場面
条件の書き方索引の効き理由
部門コード = 'D02'効く等価条件はB木を根から一直線にたどれる
給与 BETWEEN 300000 AND 400000効くB木は葉が順序どおりに並ぶので範囲も追える
氏名 LIKE '山%'効く前方一致は先頭から比較できる
氏名 LIKE '%子'効かない後方一致は先頭が定まらず、木をたどれない
ある列に関数や演算を適用した条件効かない格納された値そのものと比較していないため
該当行が表の3割になる条件効かない(全表走査が速い)1行ずつ取りに行くより順に読むほうが入出力が少ない
SELECT 部門コード, 氏名, 給与,       RANK() OVER (PARTITION BY 部門コード ORDER BY 給与 DESC) AS 部門内順位FROM 社員WHERE 部門コード IS NOT NULLORDER BY 部門コード, 部門内順位 /* GROUP BY と違い行はまとまらない。明細に順位を添えて返す */

用語

評価順序
FROM、WHERE、GROUP BY、HAVING、SELECT、ORDER BY の順に評価されるという考え方。WHEREに集約関数を書けない理由も、別名の使える場所もここから説明できる。
内部結合
結合条件に合う行が両方の表にある場合だけ結果に残す結合。相手のいない行は消えるので、一覧から漏らしたくないときは外部結合を選ぶ。
左外部結合
左に書いた表の行をすべて残し、相手のいない行では右側の列をNULLにする結合。件数を数えるときはNULLを数えないCOUNT(列名)を使う。
相関副問合せ
外側の問合せの行を参照し、行ごとに評価し直される副問合せ。「自分の部門の平均より高い」のような、行ごとに基準が変わる条件に使う。
NOT IN とNULL
副問合せの結果にNULLが1件でも含まれると、NOT IN は決して真にならない。存在しないことを調べるときは NOT EXISTS を使うのが安全。
HAVING
GROUP BY でまとめたあとのグループを絞り込む句。集約関数の条件を書ける。行単位の条件はWHEREに書いたほうが、まとめる前に減らせるので速い。
ウィンドウ関数
行をまとめずに、行ごとの値と集計や順位を同時に出す関数。OVER 句で範囲を、PARTITION BY でグループを、ORDER BY で並びを指定する。
RANK と DENSE_RANK
同点があったときの順位の付け方が違う。RANKは同順位のあとの番号を飛ばし、DENSE_RANKは飛ばさない。ROW_NUMBERは同点でも別々の番号を振る。
ビュー
問合せに名前を付けた仮想の表。実体は持たない。読みやすさとアクセス制御に使うが、集約やDISTINCTを含むものは更新できない。
索引
列の値から行の位置を引くための別構造。多くはB木の一種。検索と並べ替えを速くする代わりに、更新のたびに索引の保守コストがかかる。
選択率
条件に合う行が表全体に占める割合。これが高い(多くの行が該当する)ほど索引の効きは悪くなり、全表走査のほうが速くなる。
複合索引の左端
複数列の索引は先頭の列から順にしか使えないという性質。(A, B)の索引はAだけの検索には効くが、Bだけの検索には効かない。

例題

例題:例題:平均給与が40万円以上の部門だけを出したい。WHERE 句に AVG(給与) の条件を書けないのはなぜか。
答えと考え方 WHEREはグループ化より前、つまりまだ1行ずつしか見えていない段階で評価されるので、複数行をまとめた結果である AVG を判定できません。集約した値で絞るのはHAVINGの役目です。逆に「退職者を除く」のような行単位の条件はWHEREに書くほうが、まとめる前に対象が減るぶん速くなります。
例題:例題:(部門コード, 入社年)という順序の複合索引がある。入社年だけを条件にした検索でこの索引が効かないのはなぜか。
答えと考え方 複合索引は、先頭の列でまず並べ、その中で次の列を並べた構造だからです。電話帳が姓で並んでいるときに名前だけで探せないのと同じで、先頭の部門コードが定まらないと木をたどる出発点が決まりません。入社年だけの検索も速くしたいなら、入社年を先頭にした別の索引を追加するかどうかを、更新コストと合わせて判断します。

出典・根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

5. トランザクションと障害回復

ACIDとロック、分離レベル、ログによる回復、分散データベースとCAP定理までを一本の筋で押さえます。

業務上ひとまとまりで扱いたい一連の操作をトランザクションといい、DBMSはこれにACIDという4性質を保証します。原子性は「全部実行されるか、まったく実行されないかのどちらか」で、途中で落ちたら開始前の状態に戻します。一貫性は、実行の前後で整合性制約が守られていること。分離性は、同時に走っている他のトランザクションの途中経過が見えないこと。持続性は、コミットが返った以上、その後で障害が起きても結果が失われないことです。COMMITで確定、ROLLBACKで取消しになります。

分離性を実現する代表がロックです。読むときの共有ロックは同時に何人でも掛けられますが、書くときの専有ロックは1人だけで、共有ロックとも両立しません。ロックを掛けたり外したりを自由にすると直列化可能性が崩れるので、成長相ですべてのロックを取り、縮退相では解放だけを行う2相ロッキングを守ります。ロックの単位(粒度)を行にすると同時実行性は上がりますが管理する数が増え、表にすると管理は軽いが待ちが増えます。相反する順序で資源を取り合うとデータベースでもデッドロックが起き、DBMSは待ちグラフの循環を検出して片方をロールバックさせて解きます。ロックを使わず、更新前の版を読ませて読み手と書き手をぶつけない多版同時実行制御(MVCC)も広く使われています。

分離性を完全に保つと待ちが増えるので、実務では段階を選びます。分離レベルを下げると、まだコミットされていない値を読むダーティリード、同じ行を2度読んで値が違うノンリピータブルリード、同じ条件で2度読んで行数が違うファントムリードが順に許容されます。READ COMMITTEDはダーティリードだけを防ぎ、REPEATABLE READはノンリピータブルリードまで防ぎ、SERIALIZABLEは三つすべてを防ぎます。どこまで許すかは、その画面が正確さと応答性のどちらを重んじるかで決める設計判断です。

障害回復の土台はログです。更新の前後の値を記録した更新前ログと更新後ログを、データベース本体より先に書き出すのが先書きログ(WAL)の原則で、これが守られていれば、本体への書込みが間に合わなくてもログから復元できます。処理を止めずに一定間隔で主記憶上のバッファをまとめて書き出す点がチェックポイントで、回復のときはここから後だけを見れば済みます。

回復の手順は障害の種類で分かれます。停電などでメモリの内容が消えた障害(システム障害)では、チェックポイント以降のログを見て、コミット済みのトランザクションは更新後ログで再現するロールフォワード、未コミットのものは更新前ログで打ち消すロールバックを行います。チェックポイントより前に完了しているトランザクションは何もしなくて構いません。ディスクそのものが壊れた媒体障害では、バックアップを復元したうえで、その時点以降のログでロールフォワードします。プログラムの誤りなど、そのトランザクションだけの失敗(トランザクション障害)ではロールバックだけを行います。

データベースが複数の拠点に分かれると、全拠点で同時に確定させる仕組みが要ります。それが2相コミットで、調整者がまず全参加者に準備を問い合わせ、全員が可と答えたときだけコミットを指示します。1人でも不可ならすべて取り消します。準備の応答を返したあとに調整者が落ちると、参加者はコミットも取消しもできないまま待つブロッキングが起こり得るのが弱点です。CAP定理は、ネットワークが分断されている状況では、一貫性と可用性の両方は満たせないと述べます。分断は起きるものと考えるので、実際の選択は「分断中に古い値を返してでも応答するか、応答を止めてでも正しい値だけを返すか」になります。NoSQLの多くは前者を選び、時間がたてば全複製が同じ値に落ち着く結果整合性で運用します。

分析用途では作りが変わります。日々の業務系データベースは更新の速さを重んじますが、意思決定のために時系列で蓄えたデータウェアハウスは、更新せずに追加していき、大量の読み取りに向く形を採ります。ETLで各業務システムから抽出・変換・格納し、部門ごとに切り出したものがデータマート、加工前のまま貯めておくのがデータレイクです。分析の操作はOLAPと呼ばれ、集計軸を掘り下げるドリルダウン、まとめ上げるロールアップ、軸を入れ替えるダイシングなどがあります。中心の事実表を、商品や期間といった次元表が取り囲むスタースキーマは、結合を浅くして集計を速くするための、意図的な非正規化の例です。

分離レベルと、防げる現象(防げる/許す)
分離レベルダーティリードノンリピータブルリードファントムリード同時実行性
READ UNCOMMITTED許す許す許す最も高い
READ COMMITTED防げる許す許す高い
REPEATABLE READ防げる防げる許す中くらい
SERIALIZABLE防げる防げる防げる最も低い
ROLLBACK で戻る範囲と、COMMIT で確定する範囲
CREATE TABLE 在庫 (商品番号 TEXT PRIMARY KEY,                   数量 INTEGER NOT NULL CHECK (数量 >= 0));CREATE TABLE 出庫 (伝票番号 INTEGER PRIMARY KEY,                   商品番号 TEXT NOT NULL, 数量 INTEGER NOT NULL);INSERT INTO 在庫 VALUES ('P1', 2); /* 引当と出庫記録は、まとめて成立させないと帳簿が合わない */BEGIN;  UPDATE 在庫 SET 数量 = 数量 - 3 WHERE 商品番号 = 'P1';  /* CHECK (数量 >= 0) に反してエラー。ここで打ち切る */ROLLBACK;   /* 在庫は 2 のまま。出庫も記録されない */ BEGIN;  UPDATE 在庫 SET 数量 = 数量 - 2 WHERE 商品番号 = 'P1';  INSERT INTO 出庫 VALUES (1, 'P1', 2);COMMIT;     /* 在庫 0 と出庫1件が、同時に確定する */

用語

ACID
トランザクションが備えるべき4性質。原子性、一貫性、分離性、持続性。DBMSはロックとログでこれらを実現する。
2相ロッキング
ロックを取るだけの成長相と、解放するだけの縮退相に分ける規約。これを守るとスケジュールの直列化可能性が保証される。デッドロックは別に対処が要る。
ロックの粒度
ロックを掛ける単位。行にすると同時実行性は高いが管理数が増え、表にすると管理は軽いが待ちが増える。同時実行性と管理コストのトレードオフ。
ダーティリード
他のトランザクションがまだコミットしていない値を読んでしまうこと。READ UNCOMMITTED でだけ起こり、READ COMMITTED 以上では防がれる。
ファントムリード
同じ条件で2度検索したときに、他のトランザクションの挿入によって行数が変わる現象。SERIALIZABLE でだけ防がれる。
MVCC
多版同時実行制御。更新前の版を保持し、読み手には一貫した時点の版を見せることで、読み手と書き手が互いを待たないようにする方式。
先書きログ
WAL。データベース本体に書く前にログを確実に書き出す原則。これがあれば本体への反映が遅れても、ログから状態を復元できる。
チェックポイント
主記憶上のバッファをまとめて本体に書き出し、その時点を記録すること。回復時はここより後のログだけを見ればよくなり、復旧が短時間で済む。
ロールフォワード
更新後ログを使って、コミット済みの更新を再現する回復操作。媒体障害ではバックアップ復元後に、システム障害ではチェックポイント以降に対して行う。
2相コミット
分散したデータベースを同時に確定させる手順。調整者が準備を問い合わせ、全員が可と答えたときだけコミットする。調整者障害でのブロッキングが弱点。
CAP定理
ネットワーク分断が起きている状況では、一貫性と可用性を同時には満たせないという主張。分断中に古い値を返すか、応答を止めるかの選択になる。
スタースキーマ
中心の事実表を、商品や期間などの次元表が取り囲む分析用の構造。結合を浅くして集計を速くするための、意図的な非正規化である。
OLAP
多次元に集計されたデータを対話的に分析する操作。掘り下げるドリルダウン、まとめ上げるロールアップ、軸を入れ替えるダイシングなどがある。

例題

例題:例題:チェックポイントの後にシステム障害が起きた。チェックポイント前に開始してその後コミットしたトランザクションT1と、チェックポイント後に開始してコミットしていないT2は、それぞれどう扱うか。
答えと考え方 T1はコミット済みなので、更新後ログを使ってロールフォワードし、更新を確実に反映させます。T2は未コミットなので、更新前ログを使ってロールバックし、開始前の状態に戻します。チェックポイントより前にコミットまで終わっていたものは、すでに本体へ書き出されているので何もしません。
例題:例題:コミットが返っているのに、なぜ回復のときにロールフォワードが要るのか。
答えと考え方 先書きログの原則で保証されているのは「ログが確実に書かれていること」であって、データベース本体への反映まで終わっているとは限らないからです。本体への書込みは性能のためにバッファにためて後回しにされます。したがって、コミット済みでも本体に届いていない更新が残り得るので、更新後ログを使って再現します。逆にいえば、ログさえ残っていれば持続性は守られます。

出典・根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

確認問題(50問)

四肢択一。「正解と解説」を開くと、正解の理由と他の選択肢が違う理由を確認できます。

問1|スレッド

同じプロセスに属する複数のスレッドが共有するものはどれか。

  1. それぞれのスレッドが使うスタック領域
  2. プログラムカウンタと汎用レジスタの内容
  3. アドレス空間と、開いているファイルの記述子
  4. スレッドごとの実行状態と優先度
正解と解説
正解:C. アドレス空間と、開いているファイルの記述子

スレッドはプロセス内の実行の流れなので、アドレス空間とファイル記述子はプロセス単位で共有する。一方、スタックとレジスタ、プログラムカウンタ、実行状態はスレッドごとに個別に持たなければ、同時に別の場所を実行できない。共有しているぶん切替えが軽く通信も速いが、一つのスレッドの不正なメモリ操作がプロセス全体を巻き添えにするという弱点も、この共有から生じる。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問2|PCB

コンテキストスイッチの際に、プロセス制御ブロック(PCB)へ退避される情報として適切なものはどれか。

  1. 実行ファイルに格納された機械語命令そのもの
  2. まだ主記憶に読み込まれていないページの中身
  3. プログラムカウンタと汎用レジスタの内容
  4. 利用者が画面から入力した業務データ
正解と解説
正解:C. プログラムカウンタと汎用レジスタの内容

PCBには、そのプロセスを中断した地点から再開するために必要な情報、すなわちプログラムカウンタ、汎用レジスタの内容、優先度、状態、割当て資源などが入る。機械語命令そのものは実行ファイルと主記憶にあるので退避の必要がなく、主記憶に無いページの中身は補助記憶にある。業務データは応用プログラムが扱うもので、OSの管理情報ではない。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問3|状態遷移

プロセスの状態遷移のうち、通常は起こらないものはどれか。

  1. 待ち状態から実行状態への直接の遷移
  2. 実行可能状態から実行状態への遷移
  3. 実行状態から待ち状態への遷移
  4. 実行状態から実行可能状態への遷移
正解と解説
正解:A. 待ち状態から実行状態への直接の遷移

入出力の完了を待っていたプロセスは、待ちが解けてもいったん実行可能状態の列に並び直し、スケジューラに選ばれて初めて実行状態になる。待ち状態から実行状態へ直接移ることはない。実行可能から実行はCPUの割当て、実行から待ちは入出力要求、実行から実行可能は時間切れや横取りで、いずれも通常起こる遷移である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問4|SJF平均

4件の処理A、B、C、Dがあり、到着時刻とCPU処理時間はそれぞれ A(到着 0 ms・処理 8 ms)、B(到着 1 ms・処理 4 ms)、C(到着 2 ms・処理 9 ms)、D(到着 3 ms・処理 5 ms)である。到着済みのもののうち処理時間が最も短いものを選ぶ非プリエンプティブなSJFで実行したとき、平均ターンアラウンドタイムは何msか。

  1. 6.5
  2. 7.75
  3. 14.25
  4. 15.25
正解と解説
正解:C. 14.25

時刻0ではAしか到着していないのでAを走らせ、完了は 8 ms。この時点でB・C・Dが到着済みなので処理時間が最短のBを選び完了 12 ms、次にDで完了 17 ms、最後にCで完了 26 ms。ターンアラウンドタイムは完了時刻から到着時刻を引いた 8、11、14、24 で、合計 57、平均 14.25 ms。7.75 は待ち時間の平均(57 から処理時間の合計 26 を引いて 4 で割った値)、15.25 は到着順(FCFS)で実行したときの平均、6.5 は処理時間だけを平均した値である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問5|RR量子

ラウンドロビンスケジューリングでタイムクォンタムを極端に短くしたときに起こることはどれか。

  1. コンテキストスイッチの回数が増え、オーバヘッドの割合が大きくなる
  2. 各プロセスが完了まで実行され、到着順(FCFS)に近い動きになる
  3. 実行の順番が回ってこない処理が生じ、処理時間の短い処理が飢餓を起こしやすくなる
  4. 待たされる処理とすぐ実行される処理に分かれ、応答時間のばらつきが大きくなる
正解と解説
正解:A. コンテキストスイッチの回数が増え、オーバヘッドの割合が大きくなる

クォンタムを短くするほど、少し実行しては切り替える動きになるので、切替えそのものに費やす時間の割合が増える。到着順に近づくのは逆にクォンタムを非常に長くしたときで、処理を最後まで走らせてしまうからである。飢餓が問題になるのは優先度順やSJFであって、順番に必ず回ってくるラウンドロビンでは起きにくい。応答時間はむしろそろいやすくなる。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問6|特権モード

応用プログラムをユーザモードで、OSのカーネルだけをカーネルモードで動作させている主な狙いはどれか。

  1. 応用プログラムが特権命令や他の領域を直接操作できないようにし、障害の波及を防ぐため
  2. 特権命令を応用プログラムから直接実行させ、実行速度そのものを引き上げるため
  3. 補助記憶をページ単位で主記憶の一部として使い、主記憶の容量を実際より大きく見せるため
  4. 実行中のプロセスを一定時間ごとに切り替えて、複数のCPUに処理を均等に割り当てるため
正解と解説
正解:A. 応用プログラムが特権命令や他の領域を直接操作できないようにし、障害の波及を防ぐため

モードを分ける目的は保護である。ユーザモードでは特権命令が実行できず、他のプロセスやOSの領域にも直接触れないので、あるプログラムの誤りが全体を巻き込まない。特権が要る処理はシステムコールでカーネルに依頼するため、むしろ切替えのぶん速度は落ちる。容量を大きく見せるのは仮想記憶、CPUへの割当てはスケジューリングの役目である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問7|デッド条件

資源に通し番号を付け、どのプロセスも必ず番号の小さい順にしか資源を確保できないようにした。これによって崩されるデッドロックの発生条件はどれか。

  1. 相互排除
  2. 循環待ち
  3. 保持と待ち
  4. 横取り不可
正解と解説
正解:B. 循環待ち

確保の順序を一方向にそろえると、AがBの持つ資源を待ち、BがAの持つ資源を待つという輪ができなくなるので、循環待ちが成立しない。相互排除は資源そのものの性質なので順序では変わらず、保持と待ちを崩すには必要な資源を最初に一括して確保させる。横取り不可を崩すのは、待たされたときに持っている資源をいったん手放させる方式である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問8|資源数

5個のプロセスが、同じ種類の資源をそれぞれ最大4個まで要求する。各プロセスは必要な数がそろえば処理を終えて資源をすべて返す。どのような要求の順序であってもデッドロックが決して発生しないことを保証できる資源の最小個数はどれか。

  1. 15
  2. 16
  3. 19
  4. 20
正解と解説
正解:B. 16

最悪の配り方は、全プロセスに「あと1個で完了」という状態まで配ることで、このとき 5×(4-1) で15個が使われる。ここに1個でも余分があれば、どれか1個が完了して4個を返し、連鎖的に全員が完了できる。よって 5×(4-1)+1 で16個。15は最後の1個を足し忘れた値、20は 5×4 と単純に掛けた値、19は 5×4-1 である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問9|セマフォ

初期値が3のセマフォに対して、V操作が一度も行われないまま、異なるプロセスからP操作が4回連続して要求された。このとき起こることはどれか。

  1. 4個のプロセスがすべて資源を獲得できる
  2. 3個目のP操作の時点で待ちが発生する
  3. セマフォの値が -1 になり、4個目のP操作もそのまま通る
  4. 4個目のP操作を要求したプロセスが待ち状態になる
正解と解説
正解:D. 4個目のP操作を要求したプロセスが待ち状態になる

セマフォの値は使える資源の個数を表し、P操作のたびに1減る。初期値3なので3回のP操作で0になり、4回目は資源が残っていないため、その要求を出したプロセスが待ち状態になる。3回目までは値が1以上あるので通る。値が負になって通ってしまえば排他制御の意味がなく、待たせるためにセマフォがある。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問10|SVCの分類

スーパバイザ呼出し(SVC割込み)が内部割込みに分類される理由として、適切なものはどれか。

  1. 応用プログラムが実行した命令そのものが引き金となって発生するから
  2. OSのタイマが一定間隔で発生させるものだから
  3. 入出力装置の準備完了によって外部から通知されるから
  4. 電源やハードウェアの異常を検出したときにだけ発生するから
正解と解説
正解:A. 応用プログラムが実行した命令そのものが引き金となって発生するから

内部割込みは、実行中のプログラムの命令そのものが原因で起きるもの。SVC割込みは応用プログラムがOSの機能を呼ぶために自分で発行する命令なので内部割込みにあたる。タイマ・入出力の完了・電源異常はいずれもプログラムの外側から起きるので外部割込みである。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問11|ページ番号

仮想アドレスが32ビット、ページの大きさが8Kバイトのページング方式のシステムがある。仮想アドレスのうちページ番号に割り当てられるビット数はどれか。

  1. 12
  2. 13
  3. 19
  4. 20
正解と解説
正解:C. 19

8Kバイトは 2¹³ バイトなので、ページ内オフセットに13ビットが必要になる。残る 32-13 の19ビットがページ番号で、1プロセスあたり 2¹⁹ 個のページを持てる。13はオフセットのビット数そのもの、12と20はページの大きさを4Kバイト(2¹² バイト)と取り違えたときの値である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問12|FIFO回数

ページ参照列が 2, 3, 2, 1, 5, 2, 4, 5, 3, 2, 5, 2 である。ページフレームは3個で、当初はすべて空とする。FIFO方式で置き換えたときのページフォールトの回数はどれか。

  1. 6
  2. 7
  3. 9
  4. 12
正解と解説
正解:C. 9

最初の 2, 3 と、次の 1 でフレームが埋まって3回。以降、5、4、5、3、2、5、2 の参照時に読み込んだ順の最も古いものを追い出しながら進めると、さらに6回のフォールトが起き、合計9回になる。7は同じ列を同じ3フレームでLRUにしたときの回数、6はフレームを4個にしたときの回数、12は全参照がフォールトしたと数えたときの値である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問13|ベラディ

ページ置換アルゴリズムに関する記述のうち、適切なものはどれか。

  1. FIFOでは、ページフレームを増やしたのにページフォールトが増える場合がある
  2. LRUでは、ページフレームを増やすとページフォールトが増える場合がある
  3. FIFOはLRUより常にページフォールトが少ない
  4. LRUは参照時刻を記録しないので、FIFOより実装が軽い
正解と解説
正解:A. FIFOでは、ページフレームを増やしたのにページフォールトが増える場合がある

ページフレームを増やしたのにページフォールトが増える現象をベラディの異状といい、FIFOで起こり得る。LRUは、フレーム数を増やしたときに元の集合が必ず新しい集合に含まれるという性質をもつため、この異状は起こらない。命中率は参照の局所性に合うLRUのほうが一般に良く、LRUは参照時刻や順序の記録が要るぶん実装は重い。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問14|実効時間

主記憶へのアクセスに 100 ns、ページフォールト1回の処理に 8 ms かかるページング方式のシステムがある。ページフォールト率が 0.01% であるとき、実効アクセス時間に最も近い値はどれか。

  1. 8.1 μs
  2. 0.9 μs
  3. 0.8 μs
  4. 0.1 μs
正解と解説
正解:B. 0.9 μs

実効アクセス時間は 0.9999×100 ns と 0.0001×8 ms の和で、99.99 ns と 800 ns を足した約 900 ns、すなわち約 0.9 μs になる。0.8 μs はページフォールト側の項だけを見て主記憶アクセスの分を足し忘れた値、8.1 μs はフォールト率を 0.1% と読み違えたときの値、0.1 μs は 8 ms を 8 μs と取り違えたときの値である。1万回に1回のフォールトでも、実効アクセス時間は主記憶単独の9倍にふくらむ点が要点である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問15|スラッシング

スラッシングの説明として適切なものはどれか。また、その対策として妥当なものはどれか。

  1. 主記憶の空き領域が細切れになり大きな領域を確保できない状態。対策はコンパクション
  2. TLBの内容とページテーブルの内容が食い違う状態。対策はTLBの無効化
  3. 多重度を上げすぎてページの追い出しと読み込みばかりが起こり処理が進まない状態。対策は多重度を下げること
  4. 1ページに複数のプロセスが同時に書き込んで内容が壊れる状態。対策は排他制御
正解と解説
正解:C. 多重度を上げすぎてページの追い出しと読み込みばかりが起こり処理が進まない状態。対策は多重度を下げること

同時に走らせるプロセスを増やしすぎると、どのプロセスもワーキングセットぶんのページフレームを確保できず、追い出したページをすぐ読み直す往復だけでCPU時間が消える。これがスラッシングで、多重度を下げてワーキングセットが載るようにするのが基本の対策である。空き領域の細切れは断片化、TLBとページテーブルの不整合は別の問題であり、ページは仮想アドレス空間ごとに割り当てられるので他プロセスと同一ページを共有して壊し合うことはない。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問16|TLB

ページング方式のシステムにTLBを設けることによって得られる効果はどれか。

  1. 補助記憶を使って主記憶の容量を実際より大きく見せられる
  2. 必要なページが常に実記憶に置かれ、ページフォールトが原理的に起こらなくなる
  3. ページの読み書きをまとめて行うので、補助記憶そのもののアクセス速度が速くなる
  4. アドレス変換のたびにページテーブルを主記憶から読む必要がなくなる
正解と解説
正解:D. アドレス変換のたびにページテーブルを主記憶から読む必要がなくなる

TLBは直近のアドレス変換の結果を保持する専用の連想記憶で、ここに当たればページテーブルを主記憶から引き直さずに済む。これがないと、1回のメモリ参照のたびにページテーブルの読出しが余計に発生して倍近く遅くなる。容量を大きく見せるのは仮想記憶そのものの働きで、TLBに当たってもページが実記憶に無ければフォールトは起き、補助記憶の速度は変わらない。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問17|ページ大

ページング方式で、ページの大きさを大きくしたときに起こることとして適切なものはどれか。

  1. 1回の入出力でまとめて運べる量は増えるが、使わない部分まで読み込む無駄が増える
  2. 同じアドレス空間を表すのに必要なページ数が増え、ページテーブルも大きくなる
  3. 1ページのうち実際に使う部分の割合が高くなり、ページ内に生じる無駄(内部断片化)が減る
  4. 1回のフォールトで運ぶ量が減るので、ページフォールト1回あたりの処理時間が短くなる
正解と解説
正解:A. 1回の入出力でまとめて運べる量は増えるが、使わない部分まで読み込む無駄が増える

ページを大きくすると、同じアドレス空間を表すのに必要なページ数が減るのでページテーブルは小さくなり、まとまった量を一度に運べるので入出力の効率は上がる。その代わり、実際には使わない部分まで主記憶に載るので内部断片化が増える。フォールト1回あたりの転送量が増えるので、処理時間はむしろ長くなる方向である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問18|iノード

UNIX系ファイルシステムの i ノードが保持する情報として、適切でないものはどれか。

  1. ファイル名
  2. ファイルの所有者とアクセス権
  3. データブロックの位置
  4. 最終更新時刻
正解と解説
正解:A. ファイル名

i ノードはファイルの実体に関する属性、すなわち所有者、アクセス権、大きさ、更新時刻、データブロックの位置を持つが、ファイル名は含まない。名前と i ノード番号の対応はディレクトリ側が持つ。この分離があるので、同じ実体に複数の名前を付けるハードリンクが作れ、名前を変えても実体は動かない。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問19|ミドル

ミドルウェアに分類されるものはどれか。

  1. トランザクションの実行と資源の割当てを管理するTPモニタ
  2. 割込み処理ルーチンとデバイスドライバ
  3. CPU内部の制御を担うマイクロプログラム
  4. 業務ごとに作り込まれた入力画面と帳票のプログラム
正解と解説
正解:A. トランザクションの実行と資源の割当てを管理するTPモニタ

ミドルウェアはOSと応用プログラムの間に位置し、多くの業務で共通して必要になる機能を引き受けるソフトウェアで、DBMS、TPモニタ、Webアプリケーションサーバ、メッセージキューなどが該当する。割込み処理ルーチンとデバイスドライバはOSの一部、マイクロプログラムはハードウェア寄りの制御、業務固有の画面と帳票は応用プログラムである。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問20|分離の要件

他社の利用者どうしを同じ物理サーバに同居させる基盤を設計する。コンテナではなくハイパーバイザ型の仮想マシンを選ぶ根拠として、最も適切なものはどれか。

  1. イメージが小さく、起動が速いから
  2. カーネルを共有しないので、テナント間の分離が強く保てるから
  3. 1台あたりの集約数を最大にできるから
  4. ホストと同じ種類のOSしか動かさない前提だから
正解と解説
正解:B. カーネルを共有しないので、テナント間の分離が強く保てるから

コンテナはホストのカーネルを共有するため軽くて起動が速い反面、カーネルの脆弱性が全テナントに及ぶ。別々の会社の利用者を同居させるなら、ゲストOSごと分けるハイパーバイザ型のほうが分離が強い。イメージの小ささ・集約数の多さはコンテナ側の利点で、この場面の選択理由にはならない。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類2:コンピュータシステム 中分類5:ソフトウェア

問21|多対多

1人の医師は複数の患者を担当し、1人の患者は複数の医師の診察を受ける。この多対多の関連を担当表で表したい。担当表への4件のINSERTのうち上から3件は通り、同じ組を2度登録する4件目だけが拒否されるようにしたい。空欄アに入れる制約はどれか。

多対多を表す連関エンティティの定義
CREATE TABLE 医師 (医師番号 TEXT PRIMARY KEY, 氏名 TEXT NOT NULL);CREATE TABLE 患者 (患者番号 TEXT PRIMARY KEY, 氏名 TEXT NOT NULL);INSERT INTO 医師 VALUES ('D1','青山'),('D2','井上');INSERT INTO 患者 VALUES ('P1','上田'),('P2','遠藤'); CREATE TABLE 担当 (  医師番号 TEXT REFERENCES 医師(医師番号),  患者番号 TEXT REFERENCES 患者(患者番号),  開始日   TEXT,  [ ア ]   /* ここに制約を書く */); INSERT INTO 担当 VALUES ('D1','P1','2026-04-01');INSERT INTO 担当 VALUES ('D1','P2','2026-04-01');INSERT INTO 担当 VALUES ('D2','P1','2026-05-01');INSERT INTO 担当 VALUES ('D1','P1','2026-06-01');  /* 同じ組の重複 */
  1. PRIMARY KEY (医師番号, 患者番号)
  2. PRIMARY KEY (医師番号, 開始日)
  3. PRIMARY KEY (患者番号, 開始日)
  4. UNIQUE (医師番号), UNIQUE (患者番号)
正解と解説
正解:A. PRIMARY KEY (医師番号, 患者番号)

多対多は、双方の主キーの組を主キーとする連関エンティティで表す。アに PRIMARY KEY (医師番号, 患者番号) と書くと、D1とP1の組を2度登録する4件目だけが一意性違反で拒否され、残る3件は通る。PRIMARY KEY (医師番号, 開始日) では、同じ日に2人目の患者を登録する2件目が拒否され、1人の医師が同時に複数の患者を担当できなくなる。PRIMARY KEY (患者番号, 開始日) では4件すべてが通ってしまい、同じ組の重複を止められない。UNIQUE を2つ並べると医師も患者も1行ずつしか持てず、1対1の関連になってしまう。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問22|第3正規形

次の一連のSQLを実行すると、最後のSELECTは 2 を返した。顧客名は顧客コードによって一意に決まるはずなのに、同じ C01 に二つの名前が記録されたことになる。この受注表に関する記述として適切なものはどれか。

1か所だけ直したために起きた更新時異状
CREATE TABLE 受注 (受注番号 INTEGER PRIMARY KEY, 顧客コード TEXT NOT NULL,                   顧客名 TEXT NOT NULL, 受注日 TEXT NOT NULL,                   合計金額 INTEGER NOT NULL);INSERT INTO 受注 VALUES (1,'C01','青山商事','2026-04-01',12000);INSERT INTO 受注 VALUES (2,'C02','蒼井物産','2026-04-02', 8000);INSERT INTO 受注 VALUES (3,'C01','青山商事','2026-04-05',30000); /* 顧客名が変わったので、1件だけ直した */UPDATE 受注 SET 顧客名 = '青山商事株式会社' WHERE 受注番号 = 1; SELECT COUNT(DISTINCT 顧客名) FROM 受注 WHERE 顧客コード = 'C01';
  1. 部分関数従属があるので、第1正規形にとどまる
  2. 推移的関数従属があるので、第2正規形にとどまる
  3. すでに第3正規形を満たしている
  4. 候補キーが二つあるので、ボイスコッド正規形ではない
正解と解説
正解:B. 推移的関数従属があるので、第2正規形にとどまる

主キーは受注番号という単一項目なので、主キーの一部だけで決まる部分関数従属は原理的に存在せず、第2正規形は満たしている。しかし 受注番号 → 顧客コード → 顧客名 という推移的関数従属があるため第3正規形ではなく、同じ顧客名が3行目にも重複して書かれている。片方だけを更新すると実行例のように COUNT(DISTINCT 顧客名) が 2 になり、どちらが正しいのか分からなくなる。これが更新時異状である。顧客(顧客コード, 顧客名)を切り出して受注側に顧客コードだけを残せば、顧客名は1か所にしかなくなる。候補キーは受注番号だけなので、候補キーが二つあるという記述も当たらない。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問23|BCNF

履修(学生番号, 科目, 教員)という表がある。1人の教員は1科目だけを担当し、1人の学生が同じ科目を2人以上の教員から受けることはない。この表に関する記述として適切なものはどれか。

  1. 候補キーは {学生番号, 科目} だけであり、第3正規形かつボイスコッド正規形である
  2. 候補キーは {学生番号, 科目} と {学生番号, 教員} の二つで、第3正規形だがボイスコッド正規形ではない
  3. 部分関数従属があるので、第2正規形を満たしていない
  4. 推移的関数従属があるので、第2正規形にとどまる
正解と解説
正解:B. 候補キーは {学生番号, 科目} と {学生番号, 教員} の二つで、第3正規形だがボイスコッド正規形ではない

1人の学生が同じ科目を1人の教員からしか受けないので {学生番号, 科目} → 教員 が成り立ち、教員 → 科目 も成り立つので {学生番号, 教員} → 科目 も成り立つ。候補キーは二つである。すべての属性がどれかの候補キーに含まれるため、非キー属性の部分関数従属も推移的関数従属も存在せず第3正規形は満たす。しかし 教員 → 科目 の決定項である教員は単独では候補キーでないので、ボイスコッド正規形ではない。分解すると更新時異状は消えるが、{学生番号, 科目} → 教員 という制約が1表では表せなくなる点も判断材料になる。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問24|非正規化

商品の単価を 200 から 250 へ改定したあと、次の二つのSELECTを実行したところ、(1)は 2000 を、(2)は 2500 を返した。受注明細に単価を写して持たせるこの非正規化を選ぶ理由として最も適切なものはどれか。

写した単価と、商品表を参照した単価
CREATE TABLE 商品 (商品番号 TEXT PRIMARY KEY, 商品名 TEXT NOT NULL,                   単価 INTEGER NOT NULL);CREATE TABLE 受注明細 (受注番号 INTEGER, 行番号 INTEGER,                       商品番号 TEXT NOT NULL, 単価 INTEGER NOT NULL,                       数量 INTEGER NOT NULL,                       PRIMARY KEY (受注番号, 行番号));INSERT INTO 商品 VALUES ('P1','ノート',200);INSERT INTO 受注明細 VALUES (1,1,'P1',200,10);   /* 受注時の単価を写す */ UPDATE 商品 SET 単価 = 250 WHERE 商品番号 = 'P1';   /* 単価の改定 */ /* (1) */ SELECT 単価 * 数量 FROM 受注明細 WHERE 受注番号 = 1;/* (2) */ SELECT 商品.単価 * 受注明細.数量 FROM 受注明細          JOIN 商品 ON 受注明細.商品番号 = 商品.商品番号          WHERE 受注番号 = 1;
  1. 商品表を1件直すだけで、過去の伝票の金額もまとめて直せるから
  2. 商品表の単価が改定されても、過去の伝票に当時の単価を残せるから
  3. 同じ値を2か所に持てば、記憶容量を節約できるから
  4. 商品番号の列に参照整合性制約を掛ける必要がなくなるから
正解と解説
正解:B. 商品表の単価が改定されても、過去の伝票に当時の単価を残せるから

非正規化の代表的な理由は、結合を減らして読み取りを速くすることと、そのときの値を凍結して履歴として残すことである。実行例の(1)は受注時の単価で 2000 のままだが、商品表を参照する(2)は改定後の単価で 2500 に変わってしまい、過去の伝票の金額が書き換わったのと同じことになる。過去の伝票までまとめて直せるのはむしろ避けたい動きであり、同じ値を2か所に持てば容量は増える。参照整合性は商品番号の列に対して引き続き必要である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問25|関係の商

次のSQLは、どのような学生を求める問合せか。なお実行すると、返るのは青山の1行だけである。

関係代数の商をSQLで書いた形
CREATE TABLE 学生 (学生番号 TEXT PRIMARY KEY, 氏名 TEXT NOT NULL);CREATE TABLE 科目 (科目番号 TEXT PRIMARY KEY, 科目名 TEXT NOT NULL);CREATE TABLE 履修 (学生番号 TEXT, 科目番号 TEXT,                   PRIMARY KEY (学生番号, 科目番号));INSERT INTO 学生 VALUES ('S1','青山'),('S2','井上'),                        ('S3','上田'),('S4','遠藤');INSERT INTO 科目 VALUES ('K1','数学'),('K2','英語'),('K3','情報');INSERT INTO 履修 VALUES ('S1','K1'),('S1','K2'),('S1','K3'),                        ('S2','K1'),('S2','K2'),('S3','K1'); SELECT 氏名 FROM 学生 G WHERE NOT EXISTS (   SELECT 1 FROM 科目 K    WHERE NOT EXISTS (      SELECT 1 FROM 履修 R       WHERE R.学生番号 = G.学生番号 AND R.科目番号 = K.科目番号));
  1. 科目表にあるいずれかの科目を履修している学生
  2. 科目表にあるどの科目も履修していない学生
  3. 科目表にあるすべての科目を履修している学生
  4. 科目表にある科目を2科目以上履修している学生
正解と解説
正解:C. 科目表にあるすべての科目を履修している学生

二重のNOT EXISTSは「その学生が履修していない科目が1科目も存在しない」と読め、すべての科目を履修している学生だけが残る。これが関係代数の商(除算)に当たり、全称の条件を表す。実行例では3科目すべてを取った青山だけが返る。少なくとも1科目なら結合やEXISTS1つで書けて青山・井上・上田の3行、1科目もないなら外側のNOT EXISTSだけで遠藤の1行、2科目以上ならCOUNTとの比較で青山・井上の2行になり、いずれもこのSQLとは違う結果になる。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問26|行数計算

同じ列構成をもつ関係Rが6行、関係Sが4行あり、両方に共通する行が2行ある。次の(1)から(3)を実行したときに返る値の組合せとして正しいものはどれか。

集合演算の行数を数える
CREATE TABLE R (コード TEXT, 品名 TEXT);CREATE TABLE S (コード TEXT, 品名 TEXT);INSERT INTO R VALUES ('A1','鉛筆'),('A2','消しゴム'),('A3','定規'),                     ('A4','のり'),('A5','はさみ'),('A6','ペン');INSERT INTO S VALUES ('A5','はさみ'),('A6','ペン'),                     ('B1','付箋'),('B2','封筒'); /* (1) 直積 */SELECT COUNT(*) FROM R CROSS JOIN S;/* (2) 和 */SELECT COUNT(*) FROM (SELECT * FROM R UNION SELECT * FROM S);/* (3) 差 */SELECT COUNT(*) FROM (SELECT * FROM R EXCEPT SELECT * FROM S);
  1. 直積 24行、和 8行、差 4行
  2. 直積 24行、和 10行、差 4行
  3. 直積 10行、和 8行、差 2行
  4. 直積 24行、和 8行、差 2行
正解と解説
正解:A. 直積 24行、和 8行、差 4行

直積は行どうしの全組合せなので 6×4 で24行。UNIONは重複を1行にまとめるので 6+4-2 で8行。EXCEPTはRにあってSにない行なので 6-2 で4行になる。和を10としたのは重複をまとめない UNION ALL の行数で、差を2としたのは共通部分を求める INTERSECT の行数である。直積を10としたのは行数を足してしまった値。UNIONは自動的に重複を除き、UNION ALL は除かないという違いをここで押さえておく。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問27|外部キー

次を上から順に実行すると、(1)は成功し、(2)と(3)は拒否された。参照整合性制約に関する記述として、適切なものはどれか。

外部キーが受け付ける値と、拒否される操作
PRAGMA foreign_keys = ON;CREATE TABLE 部門 (部門コード TEXT PRIMARY KEY, 部門名 TEXT NOT NULL);CREATE TABLE 社員 (社員番号 INTEGER PRIMARY KEY, 氏名 TEXT NOT NULL,                   所属 TEXT,                   FOREIGN KEY (所属) REFERENCES 部門(部門コード));INSERT INTO 部門 VALUES ('D01','営業');INSERT INTO 社員 VALUES (101,'相沢','D01'); /* (1) */ INSERT INTO 社員 VALUES (102,'井上',NULL);/* (2) */ INSERT INTO 社員 VALUES (103,'上田','D99');/* (3) */ DELETE FROM 部門 WHERE 部門コード = 'D01';
  1. 外部キーの列には、NULLを格納することができない
  2. 参照されている親の行は、子の行が残っていても常に削除できる
  3. 外部キーの列名は、参照先の主キーの列名と必ず一致していなければならない
  4. 外部キーの値は、参照先の表に実在する値かNULLでなければならない
正解と解説
正解:D. 外部キーの値は、参照先の表に実在する値かNULLでなければならない

参照整合性制約は、外部キーの値が参照先に実在するか、まだ決まっていないことを表すNULLであることを求める。だから(1)のNULLは通り、参照先に無い D99 を入れる(2)は拒否される。(3)が拒否されたのは、子の行が残っている親を消そうとしたからで、この既定の動きがRESTRICTである。連鎖して消すCASCADEや子をNULLにするSET NULLを選べば削除できるので、常に削除できるわけでも、常にできないわけでもない。外部キーの列名は参照先の主キーと一致していなくてもよく、実行例でも 所属 と 部門コード で異なっている。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問28|候補キー

次の表定義に対し、(1)と(2)は一意性の違反で拒否され、(3)は成功した。この社員表の候補キーはいくつあるか。

一意性が保証されている列はどれか
CREATE TABLE 社員 (  社員番号     TEXT NOT NULL PRIMARY KEY,  社員証番号   TEXT NOT NULL UNIQUE,  メールアドレス TEXT NOT NULL UNIQUE,  氏名         TEXT NOT NULL,  部門コード   TEXT);INSERT INTO 社員 VALUES ('E001','C7001','[email protected]','青山','D01'); /* (1) */ INSERT INTO 社員  VALUES ('E002','C7001','[email protected]','井上','D01');/* (2) */ INSERT INTO 社員  VALUES ('E003','C7003','[email protected]','上田','D02');/* (3) */ INSERT INTO 社員  VALUES ('E004','C7004','[email protected]','青山','D01');
  1. 1
  2. 2
  3. 3
  4. 4
正解と解説
正解:C. 3

候補キーは、行を一意に識別でき、かつどの項目を欠いても識別できなくなる最小の項目の組である。実行例のとおり社員証番号が重複する(1)もメールアドレスが重複する(2)も拒否されるので、この二つは社員番号と同じく単独で行を識別できる。よって候補キーは3個で、主キーはこの中から一つを選んだにすぎない。氏名が重複する(3)が通ることから、氏名は候補キーではないと分かる。なお UNIQUE だけではNULLを複数入れられてしまうため、候補キーとして扱うには NOT NULL もそろっている必要がある。{社員番号, 社員証番号} のような組合せは最小性を満たさないので数えない。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問29|実体整合性

次の商品表に対する三つのINSERTはいずれも拒否された。このうち(1)と(2)が反した制約の説明として適切なものはどれか。

拒否された三つのINSERTと、その理由
CREATE TABLE 商品 (  商品番号 TEXT NOT NULL PRIMARY KEY,  商品名   TEXT NOT NULL,  単価     INTEGER NOT NULL CHECK (単価 > 0));INSERT INTO 商品 VALUES ('P1','ノート',200); /* (1) */ INSERT INTO 商品 VALUES ('P1','手帳',800);/* (2) */ INSERT INTO 商品 VALUES (NULL,'鉛筆',100);/* (3) */ INSERT INTO 商品 VALUES ('P2','消しゴム',-50);
  1. 外部キーを構成する列には、参照先の表に実在しない値は格納できない
  2. 列に格納できる値の範囲を、表の定義であらかじめ限定しておく
  3. 一つの問合せの中で、同じ表を2度以上参照することはできない
  4. 主キーを構成する列には、重複した値も空値(NULL)も格納できない
正解と解説
正解:D. 主キーを構成する列には、重複した値も空値(NULL)も格納できない

実体整合性制約は、すべての行が主キーによって確実に識別できることを保証する決まりで、主キーの重複とNULLを禁じる。(1)は既にある P1 と重複したため、(2)は主キーがNULLのため拒否されており、どちらもこの制約に反している。(3)は単価が0以下で CHECK (単価 > 0) に反したもので、値の範囲を限定する定義域制約である。外部キーが参照先に実在することを求めるのは参照整合性制約であり、同じ表を2度参照する自己結合は、上司と部下の関係をたどるときなどに正当に使われる。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問30|弱実体

E-R図における弱実体の例として、最も適切なものはどれか。

  1. 複数の社員が所属し、部門コードだけで識別される部門
  2. 複数の受注に現れるが、商品コードだけで識別される商品
  3. 入社時に与えられる社員番号だけで識別される社員
  4. 受注番号と行番号の組でなければ識別できない受注明細
正解と解説
正解:D. 受注番号と行番号の組でなければ識別できない受注明細

弱実体は、それ単独では識別できず、親となる実体があって初めて存在できる実体である。受注明細は「どの受注の何行目か」まで指定しないと識別できず、受注が消えれば存在意義もなくなるので弱実体に当たる。部門、商品、社員はそれぞれ独自の識別子をもち、他の実体に依存せずに存在できるので強実体である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問31|WHERE差

同じ 10 という値を使いながら、次の(1)は P1 と P2 の2行を、(2)は P2 の1行を返した。SQLのSELECT文におけるWHERE句とHAVING句の違いとして、適切なものはどれか。

絞り込む位置が変わると結果も変わる
CREATE TABLE 受注明細 (受注番号 INTEGER, 行番号 INTEGER,                       商品番号 TEXT NOT NULL, 数量 INTEGER NOT NULL,                       PRIMARY KEY (受注番号, 行番号));INSERT INTO 受注明細 VALUES (1,1,'P1',6),(1,2,'P2',5),(2,1,'P1',8),                            (2,2,'P2',20),(3,1,'P3',2),(3,2,'P3',1); /* (1) */SELECT 商品番号, SUM(数量) FROM 受注明細 GROUP BY 商品番号 HAVING SUM(数量) >= 10;/* (2) */SELECT 商品番号, SUM(数量) FROM 受注明細 WHERE 数量 >= 10 GROUP BY 商品番号;
  1. WHEREはグループ化した後に評価され、HAVINGはグループ化の前に評価される
  2. WHEREは行を1件ずつ見て絞り込み、HAVINGはグループ化した結果を絞り込む
  3. WHEREにもHAVINGにも集約関数を書くことができる
  4. HAVINGはORDER BYよりも後に評価される
正解と解説
正解:B. WHEREは行を1件ずつ見て絞り込み、HAVINGはグループ化した結果を絞り込む

評価の順番は FROM、WHERE、GROUP BY、HAVING、SELECT、ORDER BY である。(1)のHAVINGはまとめたあとの合計を見るので、P1の 6+8 と P2の 5+20 が10以上と判定されて2行になる。(2)のWHEREはまとめる前の1行ずつを見るので、数量が10以上の明細は20の1行だけになり、P2 だけが残って合計も20になる。WHEREに集約関数は書けず、HAVINGはORDER BYより前に評価される。行単位で絞れる条件をWHEREに書くと、まとめる前に対象が減るぶん速くなる。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問32|外部結合

左外部結合を使う次のSQLを実行したとき、結果は何行になるか。

相手のいない行がどう扱われるか
CREATE TABLE 部門 (部門コード TEXT PRIMARY KEY, 部門名 TEXT NOT NULL);CREATE TABLE 社員 (社員番号 INTEGER PRIMARY KEY, 氏名 TEXT NOT NULL,                   部門コード TEXT, 給与 INTEGER NOT NULL);INSERT INTO 部門 VALUES ('D01','営業'),('D02','開発'),('D03','総務'),('D04','企画');INSERT INTO 社員 VALUES (101,'相沢','D01',380000),(102,'井上','D01',420000),                        (103,'上田','D02',500000),(104,'遠藤','D02',460000),                        (105,'大川','D02',340000),(106,'加藤',NULL ,300000); SELECT * FROM 部門 LEFT OUTER JOIN 社員 ON 部門.部門コード = 社員.部門コード;
  1. 4
  2. 5
  3. 6
  4. 7
正解と解説
正解:D. 7

D01は社員2人、D02は社員3人と結び付いて5行になる。左外部結合なので、社員が1人もいないD03とD04も右側をNULLにして1行ずつ残り、合計7行になる。部門コードがNULLの加藤は左側に相手がいないので現れない。5は INNER JOIN にしたときの行数、6は社員表の行数、4は部門表の行数そのものである。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問33|人数集計

部門ごとの人数を数える次のSQLの実行結果として、正しいものはどれか。

COUNT に何を渡すかで結果が変わる
CREATE TABLE 部門 (部門コード TEXT PRIMARY KEY, 部門名 TEXT NOT NULL);CREATE TABLE 社員 (社員番号 INTEGER PRIMARY KEY, 氏名 TEXT NOT NULL,                   部門コード TEXT, 給与 INTEGER NOT NULL);INSERT INTO 部門 VALUES ('D01','営業'),('D02','開発'),('D03','総務'),('D04','企画');INSERT INTO 社員 VALUES (101,'相沢','D01',380000),(102,'井上','D01',420000),                        (103,'上田','D02',500000),(104,'遠藤','D02',460000),                        (105,'大川','D02',340000),(106,'加藤',NULL ,300000); SELECT 部門.部門名, COUNT(社員.社員番号) AS 人数  FROM 部門  LEFT OUTER JOIN 社員 ON 部門.部門コード = 社員.部門コード GROUP BY 部門.部門名;
  1. 4行が返り、総務と企画の人数はいずれも1になる
  2. 2行が返り、総務と企画は結果に現れない
  3. 7行が返り、同じ部門名が何度も並ぶ
  4. 4行が返り、総務と企画の人数はいずれも0になる
正解と解説
正解:D. 4行が返り、総務と企画の人数はいずれも0になる

左外部結合なので部門は4件すべて残り、GROUP BY 部門名 で4行になる。総務と企画には相手の社員がおらず社員番号がNULLになるが、COUNT(社員番号) はNULLを数えないので0になる。ここを COUNT(*) と書くと行そのものを数えてしまい、社員がいないのに1と表示される。INNER JOIN にすると総務と企画は消えて営業2人・開発3人の2行になり、7行になるのはGROUP BYを書かずに結合しただけの行数である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問34|COUNT

6行の社員表のうち1行だけ部門コードがNULLである。次の集約を実行したときの結果の組合せはどれか。

COUNT(*) と COUNT(列名) の違い
CREATE TABLE 部門 (部門コード TEXT PRIMARY KEY, 部門名 TEXT NOT NULL);CREATE TABLE 社員 (社員番号 INTEGER PRIMARY KEY, 氏名 TEXT NOT NULL,                   部門コード TEXT, 給与 INTEGER NOT NULL);INSERT INTO 部門 VALUES ('D01','営業'),('D02','開発'),('D03','総務'),('D04','企画');INSERT INTO 社員 VALUES (101,'相沢','D01',380000),(102,'井上','D01',420000),                        (103,'上田','D02',500000),(104,'遠藤','D02',460000),                        (105,'大川','D02',340000),(106,'加藤',NULL ,300000); SELECT COUNT(*), COUNT(部門コード) FROM 社員;
  1. 6 と 6
  2. 5 と 5
  3. 5 と 6
  4. 6 と 5
正解と解説
正解:D. 6 と 5

COUNT(*) は行そのものを数えるので、どの列がNULLでも1行と数え、結果は6になる。COUNT(列名) は指定した列がNULLの行を数えないので5になる。SUM、AVG、MAX、MINも同じくNULLを無視するため、たとえば AVG(給与) は6人ぶんの給与合計 2400000 を5で割った値ではなく、給与にNULLが無いこの表では6で割った 400000 になる。NULLを0とみなすわけではない、という点が要点である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問35|相関副問合せ

相関副問合せを用いた次のSQLを実行したとき、結果は何行になるか。

行ごとに基準が変わる副問合せ
CREATE TABLE 部門 (部門コード TEXT PRIMARY KEY, 部門名 TEXT NOT NULL);CREATE TABLE 社員 (社員番号 INTEGER PRIMARY KEY, 氏名 TEXT NOT NULL,                   部門コード TEXT, 給与 INTEGER NOT NULL);INSERT INTO 部門 VALUES ('D01','営業'),('D02','開発'),('D03','総務'),('D04','企画');INSERT INTO 社員 VALUES (101,'相沢','D01',380000),(102,'井上','D01',420000),                        (103,'上田','D02',500000),(104,'遠藤','D02',460000),                        (105,'大川','D02',340000),(106,'加藤',NULL ,300000); SELECT 氏名 FROM 社員 S WHERE 給与 > (SELECT AVG(給与) FROM 社員 T                WHERE T.部門コード = S.部門コード);
  1. 2
  2. 3
  3. 4
  4. 6
正解と解説
正解:B. 3

副問合せは外側の行ごとに評価し直される。D01の平均は400000なので井上だけが残り、D02の平均は約433333なので上田と遠藤が残って合計3行になる。加藤は部門コードがNULLで、T.部門コード = S.部門コード がどの行でも真にならず、集約対象が空のためAVGがNULLになり、比較結果が不定となって残らない。2は各部門の最高給与者だけを数えた値、4は加藤も条件を満たすと考えた値、6は自分自身を含むから必ず真になると誤解した場合の値である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問36|NOTIN罠

社員が1人も所属していない部門の部門名、すなわち総務と企画の2行を求めたい。次の表に対して意図したとおりの結果が得られるSQLはどれか。

部門コードにNULLをもつ社員が1人いる
CREATE TABLE 部門 (部門コード TEXT PRIMARY KEY, 部門名 TEXT NOT NULL);CREATE TABLE 社員 (社員番号 INTEGER PRIMARY KEY, 氏名 TEXT NOT NULL,                   部門コード TEXT, 給与 INTEGER NOT NULL);INSERT INTO 部門 VALUES ('D01','営業'),('D02','開発'),('D03','総務'),('D04','企画');INSERT INTO 社員 VALUES (101,'相沢','D01',380000),(102,'井上','D01',420000),                        (103,'上田','D02',500000),(104,'遠藤','D02',460000),                        (105,'大川','D02',340000),(106,'加藤',NULL ,300000);
  1. SELECT 部門名 FROM 部門 D WHERE D.部門コード NOT IN (SELECT S.部門コード FROM 社員 S)
  2. SELECT 部門名 FROM 部門 D WHERE NOT EXISTS (SELECT 1 FROM 社員 S WHERE S.部門コード = D.部門コード)
  3. SELECT 部門名 FROM 部門 D LEFT OUTER JOIN 社員 S ON D.部門コード = S.部門コード WHERE S.社員番号 IS NOT NULL
  4. SELECT 部門名 FROM 部門 D WHERE D.部門コード IN (SELECT S.部門コード FROM 社員 S)
正解と解説
正解:B. SELECT 部門名 FROM 部門 D WHERE NOT EXISTS (SELECT 1 FROM 社員 S WHERE S.部門コード = D.部門コード)

社員表には部門コードがNULLの加藤がいるため、NOT IN を使うと「NULLと等しくない」の判定が真でも偽でもない不定になり、条件全体が決して真にならず結果は0行になる。NOT EXISTS は行の有無だけを見るのでNULLの影響を受けず、総務と企画の2行が正しく返る。左外部結合に S.社員番号 IS NOT NULL を付けると、社員のいる部門だけを社員の人数ぶん返すので営業2行と開発3行の計5行になる。ここを IS NULL に替えれば総務と企画の2行が得られるので、不等号ならぬ否定の位置に注意する。IN は逆に営業と開発の2行を返す。存在しないことを調べるときはNOT EXISTSを選ぶのが安全である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問37|HAVING

商品ごとの数量を集計する次のSQLを実行したとき、結果に現れる商品番号はどれか。

グループにしてから絞り込む
CREATE TABLE 出荷明細 (出荷番号 INTEGER, 行番号 INTEGER,                       商品番号 TEXT NOT NULL, 数量 INTEGER NOT NULL,                       PRIMARY KEY (出荷番号, 行番号));INSERT INTO 出荷明細 VALUES (1,1,'Q1', 4),(1,2,'Q2',12),                            (1,3,'Q3', 7),(1,4,'Q4', 3),                            (2,1,'Q1', 5),(2,2,'Q3', 6),                            (2,3,'Q4', 2),(2,4,'Q5', 9); SELECT 商品番号, SUM(数量) FROM 出荷明細 GROUP BY 商品番号HAVING SUM(数量) >= 12;
  1. Q2 だけが結果に現れる
  2. Q2 と Q3 の2件が現れる
  3. Q1 と Q2 と Q3 と Q5 が現れる
  4. Q1 から Q5 まですべて現れる
正解と解説
正解:B. Q2 と Q3 の2件が現れる

商品ごとの数量の合計は Q1が9、Q2が12、Q3が13、Q4が5、Q5が9 なので、12以上になるのは Q2 と Q3 の2件である。HAVINGはグループにまとめたあとの合計を見る。これを WHERE 数量 >= 12 と書き間違えると、まとめる前の明細行を絞ってしまうので Q2 だけになる。HAVING MAX(数量) >= 12 と書いた場合もグループ内の最大値で判定するため、やはり Q2 だけである。Q5 まで含む4件になるのは、しきい値を9以上と読み違えた場合。HAVING を書き忘れれば絞り込みが効かず5種類すべてが並ぶ。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問38|順位関数

同点を含む4行に順位を付ける次のSQLを実行した。得点の高い順に並べたときの 順位A と 順位B の組合せとして正しいものはどれか。

同点があるときの順位の付き方
CREATE TABLE 成績 (受験番号 INTEGER PRIMARY KEY,                   氏名 TEXT NOT NULL, 得点 INTEGER NOT NULL);INSERT INTO 成績 VALUES (1,'青山',100),(2,'井上',90),                        (3,'上田', 90),(4,'遠藤',80); SELECT 氏名, 得点,       RANK()       OVER (ORDER BY 得点 DESC) AS 順位A,       DENSE_RANK() OVER (ORDER BY 得点 DESC) AS 順位B  FROM 成績 ORDER BY 得点 DESC;
  1. 順位A が 1, 2, 2, 3 で、順位B が 1, 2, 2, 4
  2. 順位A も 順位B も 1, 2, 3, 4 になる
  3. 順位A が 1, 2, 2, 4 で、順位B が 1, 2, 2, 3
  4. 順位A も 順位B も 1, 2, 2, 3 になる
正解と解説
正解:C. 順位A が 1, 2, 2, 4 で、順位B が 1, 2, 2, 3

順位AのRANKは同点があったときに、その人数ぶんだけ次の番号を飛ばすので 1, 2, 2, 4 になる。順位BのDENSE_RANKは飛ばさないので 1, 2, 2, 3 になる。同点でも必ず異なる番号を振るのはROW_NUMBERで、その場合は 1, 2, 3, 4 になる。順位を表彰の意味で使うならRANK、段階の数を数えるならDENSE_RANK、重複のない通し番号がほしいならROW_NUMBERを選ぶ。ウィンドウ関数はGROUP BYと違って行がまとまらないので、明細と順位を1文で並べられる。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問39|ビュー

次の四つのビューのうち、一般に更新(INSERT・UPDATE・DELETE)ができないものはどれか。

元の表の行と1対1で対応するか
CREATE TABLE 部門 (部門コード TEXT PRIMARY KEY, 部門名 TEXT NOT NULL);CREATE TABLE 社員 (社員番号 INTEGER PRIMARY KEY, 氏名 TEXT NOT NULL,                   部門コード TEXT, 給与 INTEGER NOT NULL);INSERT INTO 部門 VALUES ('D01','営業'),('D02','開発'),('D03','総務'),('D04','企画');INSERT INTO 社員 VALUES (101,'相沢','D01',380000),(102,'井上','D01',420000),                        (103,'上田','D02',500000),(104,'遠藤','D02',460000),                        (105,'大川','D02',340000),(106,'加藤',NULL ,300000); CREATE VIEW V1 AS SELECT 社員番号, 氏名 FROM 社員;CREATE VIEW V2 AS SELECT 部門コード, SUM(給与) AS 給与計                    FROM 社員 GROUP BY 部門コード;CREATE VIEW V3 AS SELECT * FROM 社員 WHERE 部門コード = 'D01';CREATE VIEW V4 AS SELECT 社員番号 AS 番号, 氏名 AS 名前 FROM 社員;
  1. V1
  2. V2
  3. V3
  4. V4
正解と解説
正解:B. V2

ビューを更新できるのは、ビューの1行が元の表の1行と1対1に対応し、どの行のどの列を直せばよいかが一意に決まる場合に限られる。V2はGROUP BYとSUMで6行を3行にまとめており、給与計を変えろと言われても元の誰の給与をいくつにするか決まらないので更新できない。V1は列を選んだだけの6行、V3はWHEREで絞った2行、V4は別名を付けただけの6行で、いずれも元の1行と対応が付くので更新できる。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問40|索引判断

複合索引を作って三つの問合せの実行計画を調べたところ、(1)と(3)は索引を使う SEARCH になったが、(2)だけが表全体を読む SCAN になった。その理由として適切なものはどれか。

複合索引が使われた問合せと、使われなかった問合せ
CREATE TABLE 社員 (社員番号 INTEGER PRIMARY KEY, 氏名 TEXT NOT NULL,                   部門コード TEXT NOT NULL, 入社年 INTEGER NOT NULL);INSERT INTO 社員 (社員番号, 氏名, 部門コード, 入社年)  WITH RECURSIVE 連番(n) AS (    SELECT 1 UNION ALL SELECT n + 1 FROM 連番 WHERE n < 1000)  SELECT n, '社員' || n, 'D' || (n % 20), 2010 + (n % 7) FROM 連番; CREATE INDEX 社員索引 ON 社員(部門コード, 入社年); /* (1) */ EXPLAIN QUERY PLAN          SELECT * FROM 社員 WHERE 部門コード = 'D3';/* (2) */ EXPLAIN QUERY PLAN          SELECT * FROM 社員 WHERE 入社年 = 2013;/* (3) */ EXPLAIN QUERY PLAN          SELECT * FROM 社員 WHERE 部門コード = 'D3' AND 入社年 = 2013;
  1. (2) は等価条件が一つしかなく、索引は2列そろわないと使えないから
  2. (2) の 入社年 は数値の列であり、数値の列には索引を作れないから
  3. 複合索引は先頭の列から順にたどるので、後ろの列だけを条件にしても使えないから
  4. (2) は該当する行が少なく、索引を使うより表を走査したほうが速いから
正解と解説
正解:C. 複合索引は先頭の列から順にたどるので、後ろの列だけを条件にしても使えないから

複合索引は(部門コード, 入社年)の順に並んだ一つの並びなので、先頭の列で位置が決まって初めて次の列をたどれる。先頭列の条件がある(1)と(3)は索引で絞り込めるが、後ろの列だけを条件にした(2)は並びの中で目的の値が散らばっており、索引をたどれず全表走査になる。(1)のように先頭列だけの条件では使えるので、2列そろわないと使えないわけではない。数値の列にも索引は作れる。また、該当行が少ないときこそ索引が効くのであって、(2)が走査になったのは該当行の数が理由ではない。逆に、該当行が表の何割にもなるような条件では、索引をたどって1行ずつ取りに行くより表を頭から読むほうが速く、最適化部が走査を選ぶこともある。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問41|原子性

次の一連の操作を行うと、ROLLBACK のあとの残高は A が 10000、B が 5000 と開始前のままだった。その後 COMMIT まで進めた二つ目の取引では、A が 7000、B が 8000 になった。この動きが表しているトランザクションの性質はどれか。

ROLLBACK した取引と、COMMIT した取引
CREATE TABLE 口座 (口座番号 TEXT PRIMARY KEY,                   残高 INTEGER NOT NULL CHECK (残高 >= 0));INSERT INTO 口座 VALUES ('A',10000),('B',5000); BEGIN;  UPDATE 口座 SET 残高 = 残高 - 3000 WHERE 口座番号 = 'A';  /* ここで異常が起きたとする。B への入金は行われていない */ROLLBACK;SELECT * FROM 口座; BEGIN;  UPDATE 口座 SET 残高 = 残高 - 3000 WHERE 口座番号 = 'A';  UPDATE 口座 SET 残高 = 残高 + 3000 WHERE 口座番号 = 'B';COMMIT;SELECT * FROM 口座;
  1. 実行の前後で、整合性制約が常に保たれていること
  2. 同時に実行されている他のトランザクションの途中経過が見えないこと
  3. コミットが完了した後は、障害が起きても結果が失われないこと
  4. 処理の全部が実行されるか、まったく実行されないかのどちらかになること
正解と解説
正解:D. 処理の全部が実行されるか、まったく実行されないかのどちらかになること

原子性は「全部実行されるか、まったく実行されないかのどちらか」を保証する性質である。実行例の一つ目は、Aから引く更新だけが済んだ状態でROLLBACKしたので、その更新も取り消されて残高は開始前に戻る。Aだけ減ってBが増えないという中途半端な状態は残らない。二つ目は両方の更新を終えてからCOMMITしたので、まとめて確定する。整合性制約が保たれることは一貫性、途中経過が他から見えないことは分離性、コミット後に失われないことは持続性であり、これら四つを合わせてACIDと呼ぶ。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問42|2相ロック

2相ロッキングプロトコルの説明として適切なものはどれか。

  1. ロックを取得する段階と解放する段階を分け、いったん解放を始めたら新たなロックを取得しないこと
  2. 分散したデータベースを、準備の問合せと確定の指示という2段階でコミットすること
  3. 共有ロックと専有ロックの2種類だけを使い、それ以外のロックを使わないこと
  4. ロックを2回に分けて掛けることで、デッドロックの発生を完全に防ぐこと
正解と解説
正解:A. ロックを取得する段階と解放する段階を分け、いったん解放を始めたら新たなロックを取得しないこと

2相ロッキングは、ロックを取るだけの成長相と、解放するだけの縮退相に分ける規約で、これを守るとスケジュールの直列化可能性が保証される。2段階でコミットするのは名前の似た2相コミットで、別の話である。ロックの種類の数を定めた規約ではなく、また直列化可能性は保証してもデッドロックそのものは防げないので、検出と回復は別に用意する必要がある。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問43|ファントム

同じ検索条件で2回検索したときに、1回目には無かった行が2回目に現れる現象と、それを防げる最も低い分離レベルの組合せはどれか。

  1. ノンリピータブルリードと、REPEATABLE READ
  2. ダーティリードと、READ COMMITTED
  3. ファントムリードと、REPEATABLE READ
  4. ファントムリードと、SERIALIZABLE
正解と解説
正解:D. ファントムリードと、SERIALIZABLE

行数そのものが変わるのはファントムリードで、これを防げるのはSERIALIZABLEだけである。REPEATABLE READは、いったん読んだ既存の行の値が変わらないことは保証するが、他のトランザクションが後から挿入した行までは抑えられない。ノンリピータブルリードは同じ行の値が変わる現象、ダーティリードは未コミットの値を読む現象である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問44|DBデッド

データベースでデッドロックが検出されたときの、DBMSの一般的な対処はどれか。

  1. 双方のトランザクションを待たせ続け、利用者の操作による解決を待つ
  2. すべてのロックをいったん解放して、両方をそのまま続行させる
  3. いずれかのトランザクションをロールバックしてロックを解放し、もう一方を進める
  4. データベース全体を停止し、バックアップとログから再構築する
正解と解説
正解:C. いずれかのトランザクションをロールバックしてロックを解放し、もう一方を進める

DBMSは待ちグラフに循環がないかを調べ、循環を見つけたら犠牲となるトランザクションを選んでロールバックし、ロックを解放して残りを進める。犠牲は、更新量が少ない、開始から間もない、といった基準で選ばれる。ロックを解放したまま続行させると更新結果が壊れるので採れず、全体を停止するのは障害回復の話であってデッドロックの対処ではない。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問45|回復処理

システム障害からの回復において、直前のチェックポイントより後に開始し、障害発生の時点でまだコミットしていなかったトランザクションに対して行う処理はどれか。

  1. 更新前ログを用いたロールバック
  2. 更新後ログを用いたロールフォワード
  3. バックアップからの媒体の復元
  4. 何もする必要はない
正解と解説
正解:A. 更新前ログを用いたロールバック

未コミットのトランザクションは、途中まで反映された更新を取り消して開始前の状態に戻さなければならないので、更新前ログを用いたロールバックを行う。コミット済みのトランザクションには更新後ログでロールフォワードを行う。バックアップからの復元が要るのはディスクが壊れた媒体障害のときであり、チェックポイントより前に完了していたものは反映済みなので何もしない。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問46|チェック点

データベースにチェックポイントを設ける目的として、最も適切なものはどれか。

  1. 障害回復のときに調べるログの範囲を限定し、復旧に要する時間を短くする
  2. トランザクションの分離レベルを一時的に引き上げる
  3. ログの内容を暗号化して、外部からの参照を防ぐ
  4. デッドロックの発生を検出する
正解と解説
正解:A. 障害回復のときに調べるログの範囲を限定し、復旧に要する時間を短くする

チェックポイントでは、主記憶上のバッファの内容をまとめてデータベース本体へ書き出し、その時点を記録する。これがあれば、回復の際にチェックポイント以降のログだけを調べればよくなり、復旧時間が大きく縮まる。分離レベルの制御、ログの暗号化、デッドロックの検出は、いずれもチェックポイントとは別の仕組みが担う。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問47|WAL

先書きログ(WAL)の原則の説明として適切なものはどれか。

  1. データベース本体を更新する前に、対応するログを確実に書き出しておく
  2. ログはデータベース本体を更新した後で、まとめて書き出す
  3. ログは主記憶にだけ保持し、補助記憶には書き出さない
  4. ログにはコミットの記録だけを残し、更新内容は残さない
正解と解説
正解:A. データベース本体を更新する前に、対応するログを確実に書き出しておく

WALは、本体への反映より先にログを確実に書き出すという原則である。これを守っていれば、本体への書込みが間に合わないうちに障害が起きても、ログから更新を再現したり取り消したりできる。順番が逆だと、本体だけ書かれてログが無い状態が生じて回復できない。ログを主記憶にだけ置けば持続性が失われ、更新内容の無いログでは回復に使えない。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問48|2相コミット

分散データベースの2相コミットにおいて、参加者が準備完了(コミット可)を応答した直後に調整者が停止した。この参加者に起こり得ることはどれか。

  1. 他の参加者も可と答えたはずなので、自分の判断で直ちにコミットしてよい
  2. 調整者が停止したこと自体を不可の応答とみなし、自分の判断で直ちにロールバックしてよい
  3. 最も早く応答した参加者が自動的に調整者の役割を引き継ぎ、全体を確定させる
  4. コミットもロールバックもできないまま待ち続ける、ブロッキングが起こり得る
正解と解説
正解:D. コミットもロールバックもできないまま待ち続ける、ブロッキングが起こり得る

準備完了を応答した参加者は、他の参加者が可と答えたか不可と答えたかを知らないため、独断でコミットもロールバックもできず、調整者の復帰を待つしかない。この待ちがブロッキングで、2相コミットの構造上の弱点である。役割を勝手に引き継ぐと、他の参加者と食い違う判断をして整合性が崩れるおそれがある。3相コミットは、この待ちを減らそうとした改良版である。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問49|CAP定理

CAP定理を、分散データベースの設計判断として言い換えたものとして最も適切なものはどれか。

  1. 一貫性・可用性・分断耐性の三つのうち好きな一つだけを選べばよく、残る二つは自動的に満たされる
  2. 三つの性質はいずれも同時に満たせるので、分断が起きている間にどう振る舞うかを設計で決めておく必要はない
  3. 分断が起きている間は、古い値を返してでも応答するか、応答を止めてでも正しい値だけを返すかを選ぶ
  4. 分断が起きないネットワークを用意すると、可用性と引換えに一貫性が保証されなくなる
正解と解説
正解:C. 分断が起きている間は、古い値を返してでも応答するか、応答を止めてでも正しい値だけを返すかを選ぶ

分断は避けられない前提なので、実際の選択は分断中の振る舞いに絞られる。一貫性を優先すれば、最新でない値を返すくらいなら応答を止めることになり、可用性を優先すれば、古い値を返してでも応答を続けることになる。三つのうち二つまでという言い方はよく使われるが、分断耐性を捨てる選択肢は現実には無い。分断が起きていない間は、一貫性と可用性の両方を満たせる。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

問50|スタースキーマ

データウェアハウスで次のようなスキーマを組み、分類と月ごとの売上を集計した。このスキーマに関する記述として適切なものはどれか。

事実表と次元表をつないで集計する
CREATE TABLE 商品次元 (商品キー INTEGER PRIMARY KEY,                       商品名 TEXT NOT NULL, 分類 TEXT NOT NULL);CREATE TABLE 期間次元 (期間キー INTEGER PRIMARY KEY,                       年 INTEGER NOT NULL, 月 INTEGER NOT NULL);CREATE TABLE 売上事実 (商品キー INTEGER, 期間キー INTEGER,                       数量 INTEGER, 金額 INTEGER);INSERT INTO 商品次元 VALUES (1,'ノート','文具'),(2,'ペン','文具'),                            (3,'コーヒー','飲料');INSERT INTO 期間次元 VALUES (1,2026,4),(2,2026,5);INSERT INTO 売上事実 VALUES (1,1,10,2000),(2,1,5,750),(3,1,20,3000),                            (1,2, 8,1600),(3,2,30,4500); SELECT 商品次元.分類, 期間次元.月, SUM(売上事実.金額) AS 売上計  FROM 売上事実  JOIN 商品次元 ON 売上事実.商品キー = 商品次元.商品キー  JOIN 期間次元 ON 売上事実.期間キー = 期間次元.期間キー GROUP BY 商品次元.分類, 期間次元.月;
  1. すべての表を第3正規形まで分解し、結合の回数を増やして更新を速くした構造
  2. 中心に置いた事実表を、商品や期間などの次元表が取り囲む構造
  3. 表を持たず、キーと値の組だけでデータを保持する構造
  4. 親子関係の木構造でデータを表す構造
正解と解説
正解:B. 中心に置いた事実表を、商品や期間などの次元表が取り囲む構造

売上事実のように数値を持つ事実表を中心に置き、商品次元・期間次元といった次元表を放射状に配置した構造がスタースキーマである。次元表をあえて正規化せずに持つことで結合を浅くし、大量の集計を速くする。実行例では2回の結合だけで分類と月の切り口が得られ、結果は文具の4月が2750、5月が1600、飲料の4月が3000、5月が4500になる。分析用途では更新より読取りの速さが重要なので、意図的な非正規化を選ぶという判断になる。キーと値の組だけで持つのはキーバリュー型のNoSQL、木構造で表すのは階層型データベースである。

根拠:IPA「応用情報技術者試験(レベル3)」シラバス Ver.7.2 大分類3:技術要素 中分類9:データベース

演習:この章の問題を解く

ランダム出題の演習ツールです(JavaScript が有効な場合に動きます)。上の「確認問題」はそのままでもすべて読めます。

※ 解説は学習用の情報提供です。最新の出題範囲・制度は必ずIPAの公式発表をご確認ください。
※ 出題はIPA公開のシラバスに沿った仮の宿 学習室のオリジナル問題です。計算問題はすべて機械検算ずみ。試験制度・実施要項はIPAの公式発表をご確認ください(2027年度春ごろに新試験制度へ移行予定)。