- 3 層スキーマと DBMS の機能、関係モデルの用語を正確に区別する
- E-R 図の多重度を、表定義の主キー・外部キーから機械的に決める
- 関数従属を見つけ、第 1 → 第 2 → 第 3 正規形へ 1 段ずつ分解する
- SQL の評価順序をもとに、結合・集計・副問合せの結果行を数える
- ロックの両立性とデッドロック、ACID 特性と隔離性水準を押さえる
- ログとチェックポイントから、ロールフォワード/ロールバックの対象を判定する
科目 A では直近 10 年(19 回)で 93 問、1 回平均 4.9 問が出ています。直近 5 回も 4〜5 問で安定しているので、例年 5 問と見て 4 問確保が目標です。科目 B では 19 回とも問 6 がデータベースで、本章の E-R 図・SQL・制約がそのまま土台になります(解き方は第 24 章)。
データベース方式と 3 層スキーマ
データベースは「データを一元管理し、複数の利用者・プログラムから矛盾なく共有する」ために存在します。その管理を担うソフトウェアが DBMS(Database Management System:データベース管理システム)で、機能は次の 3 つに大別されます。
- 定義機能: スキーマ(表・列・制約・ビュー)を定義する。SQL では DDL が担当
- 操作機能: データの検索・挿入・更新・削除を行う。SQL では DML が担当
- 制御機能: 同時実行制御(排他制御)、障害回復、機密保護(アクセス権)、保全(一貫性制約)を行う
DBMS が管理するメタデータ(データについてのデータ。表名・列名・データ型・制約・統計情報など)を集めたものをデータディクショナリ(データ辞書)といいます。設計段階の名称ゆれ(異音同義語・同音異義語)を抑えるためのデータ項目標準化も、ここに集約します。
3 層スキーマアーキテクチャ
3 層スキーマは、データの見え方を 3 段に分けてデータ独立性を確保する考え方です。上下の層を切り離しておくと、片方を変えてももう片方を直さずに済みます。
| スキーマ | 何を定義するか | 典型的な中身 |
|---|---|---|
| 外部スキーマ(副スキーマ) | 利用者・プログラムから見た部分的なデータ構造 | ビュー表、画面や帳票が必要とする項目 |
| 概念スキーマ | 対象業務全体の論理構造。機器や DBMS に依存しない | 表・列・主キー・外部キー・関連 |
| 内部スキーマ(記憶スキーマ) | 記憶装置上の物理的な格納方法 | ファイル編成、インデックス定義、ページ長 |
データモデルとデータベースの種類
論理データモデルは「データの論理構造をどう表すか」の型です。試験で問われるのはほぼ関係モデルですが、種類の名前と構造の対応は用語問題として出ます。
| 種類 | データ構造 | 特徴 |
|---|---|---|
| 階層型(HDB) | 木構造。親 1 に対し子は複数 | アクセス経路が 1 本に決まる。多対多を直接表せない |
| 網型(NDB) | 網構造。バックマン線図で表現 | 多対多を表せるが、経路の指定が複雑 |
| 関係型(RDB) | 2 次元の表(関係) | 集合演算で操作。SQL で扱う。現在の主流 |
| オブジェクト指向型(OODB) | データと手続をまとめたオブジェクト | 継承・カプセル化をそのまま格納できる |
| XML データベース | 木構造の XML 文書 | 半構造化データを変換せずに保持できる |
| グラフ型 | プロパティグラフ、トリプルストア | ノードとエッジで関係そのものを表す |
| インメモリデータベース | 主記憶上にデータを常駐 | ディスク入出力が無く応答が速い |
関係モデルの用語は科目 B の記述でも使うので、別名まで対応づけて覚えます。関係(リレーション)=表、タプル=行(組)、属性=列(フィールド)、定義域(ドメイン)=属性が取りうる値の集合、実現値=実際に格納された値、関係スキーマ=関係の構造の定義です。関係は「タプルの集合」なので、同じタプルが 2 つ存在せず、行にも列にも順序の意味はありません。
データ分析の進め方には、企業データモデルから降ろすトップダウンアプローチと、既存の帳票・画面から積み上げるボトムアップアプローチがあり、データを中心に据えて業務を設計する考え方を DOA(Data Oriented Approach:データ中心アプローチ)といいます。
概念設計 ― E-R 図と多重度
概念設計では、業務に登場する「もの・こと」をエンティティ、その性質を属性、エンティティ間の関わりをリレーションシップとして整理し、E-R 図(Entity-Relationship Diagram)に描きます。試験で問われるのはほぼ 1 点、関連線の向き(カーディナリティ=多重度)です。
多重度は感覚で決めず、表定義から機械的に導きます。一方の主キーが、他方に外部キーとして入っていれば、主キー側が「1」・外部キー側が「多」です。どちらにも入っていなければ多対多を疑い、両方の主キーを持つ連関エンティティ(交差エンティティ)に分解します。
| 表したいこと | E-R 図(IPA の記法) | UML クラス図の多重度 |
|---|---|---|
| 1 対 1 | 両端に矢印なし(または 1 と 1) | 1 — 1 |
| 1 対多 | 「多」側へ矢印を 1 本 | 1 — 0..* または 1 — 1..* |
| 多対多 | 両端へ矢印 | 0..* — 0..* |
| 必ず 1 件以上ある | — | 1..* |
| 無くてもよい(省略可) | — | 0..1 |
設計判断でよく使う型
- サロゲートキー(代用キー): 業務上のコードが変更されうる・桁数が変わりうるとき、意味を持たない連番の主キーを別に立てる。業務コードは一意性制約で守る
- スーパータイプ/サブタイプ: 「講座」の共通属性を親に、「対面講座」「オンライン講座」の固有属性を子に分ける
- 自己参照関連: 「社員」の上司も社員、「組織」の親も組織。同じ表を 2 回使うので、SQL では自己結合になる
- 履歴保持: 単価や住所が変わっても過去伝票を再現したいときは、伝票側に発生時点の値を持たせるか、有効期間(開始日・終了日)を属性に追加する
正規化 ― 関数従属と第 1〜第 3 正規形
正規化の目的は更新時異状(更新の抜け・矛盾)の排除です。1 つの表に何でも詰め込むと、顧客名を直すのに何百行も更新することになり、直し漏れが矛盾になります。正規化はこれを「1 つの事実は 1 か所に」の形へ分解する手続きです。
土台は関数従属です。属性 X の値が決まれば属性 Y の値が 1 つに決まるとき、Y は X に関数従属するといい、X → Y と書きます。ここから 3 つの型が出ます。
- 完全関数従属: 複合キーのすべてが揃って初めて決まる(受注番号 + 商品コード → 数量)
- 部分関数従属: 複合キーの一部だけで決まってしまう(受注番号 → 受注日)
- 推移的関数従属: キー → A → B と 2 段で決まる(受注番号 → 顧客コード → 顧客名)
判定の型: どの正規形まで来ているか
第 1 正規形 ⇔ 繰返し項目が無く、すべての属性が単一値/第 2 正規形 ⇔ 非キー属性の部分関数従属が無い/第 3 正規形 ⇔ 非キー属性の推移的関数従属が無い
例題: 受注明細(受注番号, 商品コード, 受注日, 顧客コード, 顧客名, 商品名, 数量)。主キーは受注番号 + 商品コード。何正規形か、また第 3 正規形へ分解せよ。
- 候補キーを確定する: 1 行を一意に決めるのは 受注番号 + 商品コード(複合キー)
- 非キー属性がキー全体に依存するか見る: 受注日・顧客コード・顧客名は受注番号だけで、商品名は商品コードだけで決まる = 部分関数従属あり。よって第 1 正規形止まり
- 部分関数従属を切り出す: 受注(受注番号, 受注日, 顧客コード, 顧客名)/商品(商品コード, 商品名)/受注明細(受注番号, 商品コード, 数量)= 第 2 正規形
- 残った非キー属性同士の従属を探す: 受注表に 受注番号 → 顧客コード → 顧客名 の推移的関数従属。顧客(顧客コード, 顧客名)へ切り出す
答え: 第 1 正規形。第 3 正規形は 受注(受注番号, 受注日, 顧客コード)/顧客(顧客コード, 顧客名)/商品(商品コード, 商品名)/受注明細(受注番号, 商品コード, 数量)の 4 表です。
| 正規形 | 満たす条件 | 取り除かれる異状 |
|---|---|---|
| 非正規形 | 繰返し項目(1 行に明細が複数列)がある | — |
| 第 1 正規形 | すべての属性が単一値。繰返しを別行に展開 | 行あたりの項目数が不定になる問題 |
| 第 2 正規形 | 第 1 正規形かつ、非キー属性が候補キーに完全関数従属 | キーの一部だけで決まる値の重複更新 |
| 第 3 正規形 | 第 2 正規形かつ、非キー属性が候補キーに推移的関数従属しない | 非キー属性経由で決まる値の重複更新 |
| ボイスコッド正規形 | すべての関数従属の決定項が候補キーである | 候補キーが複数あり重なるときの異状 |
候補キーが 1 つしかなく、それが単一の属性なら、第 3 正規形とボイスコッド正規形は一致します。両者が食い違うのは、候補キーが複数あって属性を共有している場合だけです。
逆に、分解しすぎると結合の回数が増えて検索が遅くなります。非正規化は、更新が少なく参照が圧倒的に多い表であえて冗長を残し、結合を減らす性能設計です。集計値をあらかじめ持つ(派生属性)のも同じ考え方で、更新時に矛盾させない仕掛け(トリガや夜間バッチ)とセットにします。
キーと制約 ― 参照整合性とビュー
キーは「行を特定するための属性の組」です。行を一意に決められる属性の組すべてが候補キー、その中から設計者が 1 つ選んだものが主キーで、主キーには一意性制約と非 NULL 制約が同時に効きます。選ばれなかった候補キーは代替キーです。外部キーは、他の表(または自表)の主キー・候補キーを参照する属性で、これによって表と表がつながります。
参照整合性(参照制約)は「外部キーの値は、参照先に必ず実在する」という約束です。この約束を壊す操作だけが拒否される、という向きを取り違えないことが得点の分かれ目になります。
| 制約 | 意味 | SQL での書き方 |
|---|---|---|
| 一意性制約 | 重複した値を許さない。NULL は複数入れられる | UNIQUE |
| 非 NULL 制約 | 未入力を許さない | NOT NULL |
| 主キー制約 | 一意性 + 非 NULL。表に 1 つ | PRIMARY KEY |
| 参照制約 | 参照先に実在する値だけを許す | FOREIGN KEY ... REFERENCES ... |
| 検査制約 | 値の範囲・条件を限定する | CHECK (数量 > 0) |
CREATE TABLE 社員 (
社員番号 CHAR(6) NOT NULL,
氏名 VARCHAR(40) NOT NULL,
メール VARCHAR(120) UNIQUE,
部門コード CHAR(4),
基本給 INTEGER CHECK (基本給 >= 0),
PRIMARY KEY (社員番号),
FOREIGN KEY (部門コード) REFERENCES 部門(部門コード)
ON DELETE SET NULL
);
ALTER TABLE 社員 ADD CONSTRAINT uq_氏名_部門 UNIQUE (氏名, 部門コード);
後から制約を足すときは ALTER TABLE を使います。既存データに重複があると UNIQUE の追加は失敗するので、先に重複を 1 件だけ残して削除する、という順序が科目 B でも問われます。
ビューとアクセス権
ビュー(導出表)は、SELECT 文に名前を付けたものです。実データは持たず、参照されるたびに元の実表から作られます。利用者に見せたい列・行だけを切り出せるので、外部スキーマとアクセス制御の両方を担います。
CREATE VIEW 営業部社員 (社員番号, 氏名) AS
SELECT 社員番号, 氏名 FROM 社員 WHERE 部門コード = 'S001';
GRANT SELECT, INSERT ON 営業部社員 TO 営業管理者;
REVOKE INSERT ON 営業部社員 FROM 営業管理者;
ビューへの更新は、その 1 行が元表のどの行に対応するか一意に決まる場合だけ可能です。射影と選択だけで作ったビューは更新可能、集約関数・GROUP BY・DISTINCT・UNION を含むビューは更新不可と覚えます。列名はビュー定義で別名を付けられます。
権限は GRANT 権限 ON 対象 TO 利用者 で与え、REVOKE で取り消します。権限の種類は SELECT(参照)・INSERT(挿入)・UPDATE(更新)・DELETE(削除)などで、WITH GRANT OPTION を付けると受け取った側が他人へ再付与できます。
関係代数と SQL ― 結合・集計・副問合せ
関係データベースの操作は、集合の演算として定義されています。SQL はこの関係代数に文法を与えたものなので、演算の名前と結果の形を先に押さえると SQL の読み違いが減ります。
| 演算 | 何をするか | SQL での対応 |
|---|---|---|
| 選択 | 条件に合う行を取り出す | WHERE 句 |
| 射影 | 指定した列を取り出す | SELECT の列並び |
| 結合 | 2 つの表を共通の値でつなぐ | JOIN ... ON |
| 直積 | すべての行の組合せを作る(m × n 行) | CROSS JOIN、FROM に表を並べる |
| 和・差・共通(積) | 2 つの表を集合として合成する | UNION/EXCEPT/INTERSECT |
| 商 | 「すべての◯◯を満たす」行を取り出す | NOT EXISTS の二重否定で書く |
和・差・共通は、列数と各列の定義域が一致していること(和両立)が前提です。自然結合は、同名の列で等結合したうえで重複する列を 1 つにまとめた結合を指します。
SELECT 文は書いた順ではなく決まった順で評価される
SQL の各句は、記述順ではなく評価順で動きます。WHERE に集約関数を書けない理由も、SELECT で付けた別名を WHERE で使えない理由も、この順序で説明できます。
結合と NULL
結合は「どちらの表の行を残すか」で型が分かれます。実績が無い側も残したいという要件が出たら外部結合、というのが科目 B の定番パターンです。
| 結合 | 残る行 | NULL の出方 |
|---|---|---|
| 内部結合(INNER JOIN) | 結合条件が成立した組合せだけ | 出ない(対応が無い行は消える) |
| 左外部結合(LEFT OUTER JOIN) | 左表は全行、右表は対応があれば | 右表側の列が NULL になる |
| 右外部結合(RIGHT OUTER JOIN) | 右表は全行、左表は対応があれば | 左表側の列が NULL になる |
| 完全外部結合(FULL OUTER JOIN) | 両表の全行 | 対応の無い側が NULL になる |
| 交差結合(CROSS JOIN) | すべての組合せ(m × n 行) | 出ない |
| 自己結合 | 同じ表に別名を 2 つ付けて結合 | 結合の型に従う |
SELECT S.部門コード, B.部門名,
COALESCE(SUM(T.金額), 0) AS 売上合計
FROM 部門 B
LEFT OUTER JOIN 売上 T ON B.部門コード = T.部門コード
INNER JOIN 部門 S ON S.部門コード = B.部門コード
GROUP BY S.部門コード, B.部門名
HAVING COALESCE(SUM(T.金額), 0) < 1000000
ORDER BY 売上合計 DESC;
外部結合で対応が無かった側は NULL になり、SUM は NULL を無視するのでグループ全体が NULL になります。0 で見せたいときは COALESCE(最初の非 NULL を返す)で置き換えます。NULL は「値が無い」ことを表す印なので、= NULL では判定できず IS NULL を使い、比較・算術に混ざると結果も NULL になります。
集計では、SELECT に書ける非集約の列は GROUP BY に並べた列だけ(SQL:1999 以降は GROUP BY 列に関数従属する列を例外的に許す規格・実装もありますが、試験対策としては原則どおりに考えます)、という規則が効きます。COUNT(*) は行数、COUNT(列) は NULL を除いた件数で、両者の差がひっかけになります。
副問合せと相関副問合せ
副問合せ(サブクエリ)は SELECT 文の中の SELECT 文です。内側が外側の別名を参照していれば相関副問合せで、外側の 1 行ごとに内側が評価し直されます。参照していなければ 1 回だけ評価される単純な副問合せです。
計算の型: 副問合せの結果行数を数える
数え方: 外側の表の行数から出発し、内側が「1 行でも返るか」で 1 行ずつ採否を決める。EXISTS は返れば真、NOT EXISTS は返らなければ真。
例題: 社員表に S01〜S05 の 5 行、出張申請表に(S01, 大阪)(S01, 福岡)(S03, 札幌)の 3 行があるとき、次の SQL の結果はいくつか。
SELECT COUNT(*) FROM 社員 A
WHERE NOT EXISTS (
SELECT 1 FROM 出張申請 B
WHERE B.社員番号 = A.社員番号 );
- 外側の行を並べる: S01, S02, S03, S04, S05 の 5 行
- 内側が外側の別名 A を参照しているので相関副問合せ。行ごとに評価する
- S01 は 2 行返る → NOT EXISTS は偽で除外。S03 は 1 行返る → 除外。S02・S04・S05 は 0 行 → 真で採用
- 採用された行を数える: 3 行
答え: 3。EXISTS に読み違えると 2、NOT IN に置き換えて内側に NULL が混ざると 0 件になる、という 2 段のひっかけが用意されます。
SELECT 部門コード, 氏名, 基本給,
RANK() OVER (PARTITION BY 部門コード ORDER BY 基本給 DESC) AS 部門内順位,
CASE WHEN 基本給 >= 400000 THEN '上位' ELSE '一般' END AS 区分
FROM 社員
WHERE 部門コード IN (SELECT 部門コード FROM 部門 WHERE 拠点 = '東京');
ウィンドウ関数は、GROUP BY のように行をまとめずに、行を保ったまま集計・順位付けを行う仕組みです。OVER (PARTITION BY ... ORDER BY ...) で「どの範囲を、どの順に見るか」を指定します。シラバス Ver.7.2 の用語例に入っており、直近では令和 6 年秋に出題されました。
集合演算は UNION(和・重複除去)、UNION ALL(和・重複そのまま)、EXCEPT(差)、INTERSECT(共通)です。UNION は重複除去のための処理(多くはソート、実装によってはハッシュ集約)が入るので、重複がないと分かっているなら UNION ALL のほうが速くなります。
DDL・DML・DCL と、プログラムからの利用
SQL は役割で 3 つに分かれます。DDL(データ定義言語)は CREATE/ALTER/DROP、DML(データ操作言語)は SELECT/INSERT/UPDATE/DELETE、DCL(データ制御言語)は GRANT/REVOKE/COMMIT/ROLLBACK です(IPA のシラバスは DCL という区分を使わず、DDL/DML の 2 分類で GRANT 文などを「その他のデータ操作言語」として扱います)。
SQL を単独で使うのが独立言語方式(会話型 SQL)、他の言語の中に埋め込むのが親言語方式(埋込み SQL)です。埋込み SQL では、複数行が返る問合せをプログラムの変数へ 1 行ずつ受け取るためにカーソルを使い、DECLARE(宣言)→ OPEN(開始)→ FETCH(読込み)→ CLOSE(終了)の順に操作します。値を渡すときは :変数名 の形の埋込み変数を使います。
ストアドプロシージャは、一連の SQL を DBMS 側に登録しておき、名前で呼び出す仕組みです。1 回の呼出しで複数の SQL がサーバ内で実行されるので、クライアントとサーバ間の通信量が減るのが最大の利点で、この 1 点がそのまま繰り返し出題されています。あらかじめ構文解析・最適化を済ませられる点も利点です。これに対しトリガは、表への INSERT/UPDATE/DELETE を契機に自動起動する処理で、呼び出して使うものではありません。
CALL で明示的に呼び出します。なお、利用者の入力を文字列連結で SQL に埋め込むと SQL インジェクションを招きます。対策はプレースホルダ(バインド機構)による値の受け渡しで、詳細は第 12 章で扱います。
物理設計 ― インデックスと性能
物理設計は、アクセス効率と記憶効率の観点で「どう格納するか」を決める工程です。試験で問われるのはほぼインデックスの選び方で、B+ 木とハッシュの得意分野の対比が固定の出題パターンになっています。
| インデックス | 得意な検索 | 注意点 |
|---|---|---|
| B+ 木(B-tree) | 完全一致・範囲・前方一致・整列 | 挿入でノード分割が起きる。探索コストは木の高さに比例 |
| ハッシュ | 完全一致のみ | 範囲検索・整列に使えない。衝突時の連鎖に注意 |
| ビットマップ | 値の種類が少ない列(性別・区分)の組合せ条件 | 更新が多い表には向かない |
| ユニークインデックス | 一意性の保証を兼ねた検索 | 重複データがあると作成に失敗する |
| クラスタ化インデックス | キー順に実データを並べる。範囲取得が速い | 1 表に 1 つだけ |
| カバリングインデックス | 必要な列がすべて索引に含まれ、表を読まずに済む | 索引が大きくなる |
| 転置インデックス | 全文検索(単語からどの文書にあるかを引く) | 語の切り出し方式に依存する |
インデックスは万能ではありません。更新のたびに索引も書き換わるので、索引を増やすほど INSERT/UPDATE/DELETE は遅くなります。また、値の種類が少ない列(選択率が悪い列)や、列に関数を適用した条件、前方一致でない LIKE '%語%' では効かないことが多く、表全体を読む処理では索引を使わないほうが速い場合もあります。どの経路で実行するかを統計情報から判断するのがコストベースオプティマイザで、統計情報が古いと誤った実行計画を選びます。
そのほかの物理設計の道具として、行を条件で分ける水平分割、列を使用頻度で分ける垂直分割、ディスク容量見積り、最適ブロック(ページ)長の設計、圧縮(コンプレッション)と伸張(デコンプレッション)があります。運用開始後は、断片化した領域を詰め直す再編成と、実行計画を改善するチューニングが保守作業になります。
トランザクションと同時実行制御
トランザクションは「これ以上分けられない一連の処理」です。振替なら「A 口座から引く」と「B 口座へ足す」で 1 つ。途中で止まると口座の合計が合わなくなるので、DBMS は次の 4 性質(ACID 特性)を保証します。
| 特性 | 意味 | 実現する仕組み |
|---|---|---|
| 原子性(Atomicity) | すべて実行されるか、まったく実行されないかのどちらか | コミット/ロールバック |
| 一貫性(Consistency) | 実行の前後で整合性制約が保たれる | 一意性制約・参照制約・検査制約 |
| 独立性(Isolation) | 同時に走る他のトランザクションの影響を受けない | 同時実行制御(ロック・MVCC) |
| 耐久性(Durability) | コミットした結果は障害が起きても失われない | ログの先書き(WAL)とロールフォワード |
ロックと両立性
同時実行制御の基本はロックです。読むだけなら他人と共有してよいので共有ロック(S ロック)、書くなら独占しなければならないので専有ロック(X ロック)を掛けます。両立するのは共有ロック同士だけです。
| 後から要求 | 相手が共有ロック中 | 相手が専有ロック中 |
|---|---|---|
| 共有ロック | 両立する(待たない) | 両立しない(待つ) |
| 専有ロック | 両立しない(待つ) | 両立しない(待つ) |
ロックを掛ける単位がロック粒度です。行単位に細かくすると同時実行性は上がりますが、管理するロックの数と処理の負荷が増えます。表単位に粗くすると管理は軽くなりますが、待たされる相手が増えます。
2 相ロッキングプロトコルは、トランザクションを「ロックを獲得していく成長相」と「解放していく縮退相」に分け、いったん解放を始めたら新たなロックを取らない、という規則です。これを守ると直列化可能性が保証されますが、デッドロックは防げません。
デッドロックへの対処は、検出して片方をロールバックする(犠牲者の選択)か、そもそも起こさないように資源へのアクセス順序を全トランザクションで統一するかです。タイムスタンプを使う予防方式には、後発を諦めさせる Wait-Die 方式と、先発が後発を強制終了させる Wound-Wait 方式があります。
ロックを使わない方式が多版同時実行制御(MVCC)です。更新時に古い版(バージョン)を残し、参照する側は自分が開始した時点の版を読みます。読み手と書き手が待ち合わせないので同時実行性が高く、直近では令和 7 年秋に出題されました。更新の衝突を事前にロックで防ぐのが悲観ロック、更新直前に「他人に変えられていないか」を確認する(更新前後で版番号を比較する)のが楽観ロックです。
隔離性水準と 3 つの異常
独立性を厳しくするほど安全ですが同時実行性は落ちます。そのトレードオフを段階にしたのが隔離性水準で、水準ごとに許してしまう異常が決まっています。
| 隔離性水準 | ダーティリード | ノンリピータブルリード | ファントムリード |
|---|---|---|---|
| READ UNCOMMITTED | 起こる | 起こる | 起こる |
| READ COMMITTED | 防げる | 起こる | 起こる |
| REPEATABLE READ | 防げる | 防げる | 起こる |
| SERIALIZABLE | 防げる | 防げる | 防げる |
- ダーティリード: 他人がまだコミットしていない値を読んでしまう
- ノンリピータブルリード: 同じ行を 2 回読むと、間に更新されて値が変わっている
- ファントムリード: 同じ条件で 2 回検索すると、間に挿入された行が増えている
長時間の処理を 1 つのトランザクションにまとめられない場面では、後から打ち消す処理を用意する補償トランザクションを組み合わせます。複数サービスにまたがる更新を、ローカルトランザクションと補償で連鎖させる設計が Saga パターン、仮押さえ・確定・取消の 3 段階に分けるのが TCC パターンです。同じ要求が二重に届いても結果が変わらない性質(べき等性)を持たせておくと、再送時の二重登録を防げます。
障害回復 ― ログ・チェックポイント・2 相コミット
DBMS はデータを更新する前に、更新前の値(更新前ログ)と更新後の値(更新後ログ)をジャーナルファイル(ログファイル)へ先に書きます。この順序を守るからこそ、後から「戻す」も「やり直す」もできます。
チェックポイントは、その時点でメモリ上のバッファをディスクへ書き出し、印をログに記録する処理です。回復のたびにログの先頭まで遡らずに済み、再開時間が短くなります。
判定の型: ロールフォワードかロールバックか
判定式: 障害時点でコミット済 かつ チェックポイント後にコミット → ロールフォワード(更新後ログで再現)/障害時点で未コミット → ロールバック(更新前ログで戻す)/チェックポイント前にコミット済 → 何もしない
例題: 図 9-9 の T1〜T4 について、システム障害(メモリ内容の消失)からの回復操作をそれぞれ答えよ。
- チェックポイントの線と、障害の線を引く
- 各トランザクションのコミット(●)が、2 本の線のどちら側にあるかを見る
- T1: チェックポイント前にコミット済 → ディスクに反映済みなので回復不要
- T2: チェックポイント後・障害前にコミット済 → ロールフォワード
- T3・T4: 障害時点でコミットしていない → ロールバック(T4 のようにチェックポイント後に始まったものも同じ)
答え: T1 回復不要、T2 ロールフォワード、T3・T4 ロールバック。媒体障害(ディスク故障)の場合は前提が変わり、まずバックアップをリストアしてから、そこ以降のコミット済トランザクションをすべてロールフォワードします。
| 障害の種類 | 何が壊れたか | 回復操作 |
|---|---|---|
| トランザクション障害 | デッドロックや異常終了で 1 つの処理が中断 | そのトランザクションだけロールバック |
| システム障害 | 電源断などでメモリ内容が消失(ディスクは無事) | 再起動時にチェックポイント以降をロールフォワード+未コミット分をロールバック |
| 媒体障害 | ディスクが物理的に故障 | バックアップをリストアし、以降のログでロールフォワード |
バックアップは、全体を取るフルバックアップ、前回のフルバックアップからの変更分を取る差分バックアップ、前回のバックアップ(種類を問わず)からの変更分を取る増分バックアップがあります。差分は復元がフル 1 本+差分 1 本で済み、増分は取得が速い代わりに復元でフル 1 本+増分すべてが要ります。
そのほか、更新をページ単位の写しに書いて最後に切り替えるシャドウページ法、ログを使った回復処理を伴う再起動をウォームスタート、ログを使わず初期状態から立ち上げる再起動をコールドスタートと呼びます。
分散環境のコミット ― 2 相コミット
更新が複数のデータベースにまたがると、片方だけコミットされる事態を避ける必要があります。そこで、調停者(コーディネータ)が全参加者に「コミットできるか」を尋ねてから確定させるのが 2 相コミットです。
危ないのは、調停者が第 2 相の決定を送る直前に落ちる場合です。参加者はコミットともロールバックとも決められないまま資源をロックし続けます(ブロッキング)。この弱点を突く出題が令和 6 年秋にありました。
NoSQL・分散データベースとデータ活用
関係データベースは表とスキーマを固定して整合性を守る代わりに、水平方向への拡張が苦手です。そこで、用途を絞って拡張性・柔軟性を優先したのが NoSQL(Not only SQL)です。直近 3 年で最も出題が伸びた領域で、「この要件ならどの型か」を選ばせる形が増えています。
| 分類 | データの持ち方 | 向く用途 |
|---|---|---|
| キーバリュー型(KVS) | キーと値の対だけ | セッション情報、キャッシュ。単純で最も速い |
| ドキュメント指向型 | JSON や XML の文書を 1 件として格納 | 項目の構成が案件ごとに異なるデータ |
| 列指向型(ワイドカラム) | 行キーの下に列群を持ち、列単位で格納 | 大量データの一部の列だけを集計する分析 |
| グラフ型 | ノードとエッジ、それぞれの属性 | 人間関係、経路、推薦などのつながりの探索 |
分散システムでは CAP 定理が効きます。一貫性(Consistency)・可用性(Availability)・分断耐性(Partition tolerance)の 3 つを同時に完全には満たせず、ネットワーク分断が起きたときに一貫性と可用性のどちらを取るかを選ぶことになる、という主張です。ここで可用性を優先する立場の性質が BASE(Basically Available, Soft state, Eventually consistent)で、更新直後は不揃いでも、やがて全複製が同じ値に落ち着く結果整合性を許します。
| 観点 | ACID(関係データベース) | BASE(多くの NoSQL) |
|---|---|---|
| 一貫性の扱い | 常に整合した状態を保つ | 一時的な不整合を許し、やがて収束させる |
| 優先するもの | 正確さ | 可用性と応答性 |
| 典型的な用途 | 会計・在庫・決済 | ログ収集、SNS のタイムライン、閲覧履歴 |
分散データベースでは、利用者に「分散していること」を意識させない透過性が目標です。位置の透過性(どのサイトにあるか意識しない)、複製に対する透過性(複製の存在と数を意識しない)、分割に対する透過性(表が分けられていることを意識しない)などがあります。表を行で分けて配置するのが水平分散、列で分けるのが垂直分散、同じ内容の複製を複数サイトに持つのがレプリケーション、キーの範囲でデータを別サーバへ振り分けて負荷を分けるのがシャーディングです。ネットワーク分断で両系が「自分が主」と思い込む状態をスプリットブレインといいます。
分析のためのデータベース
日々の業務処理(OLTP)と分析(OLAP)では、求められる形が違います。OLTP は小さな更新を大量にさばくため正規化しますが、OLAP は大量の行をまとめて集計するので、あえて非正規化した構造を使います。
| 用語 | 意味 | 押さえどころ |
|---|---|---|
| データウェアハウス(DWH) | 意思決定のために時系列で蓄積した統合データ | 更新せず追加していく。削除しない |
| データマート | DWH から特定部門・用途向けに切り出した小さな倉庫 | 参照範囲を絞って応答を速くする |
| スタースキーマ | 中心のファクト表を、周囲のディメンション表が囲む形 | ファクト表の主キーは集計粒度(例: 日付 + 店舗 + 商品) |
| ETL/ELT | 抽出・変換・格納(ELT は格納してから変換) | 途中でデータクレンジング(表記ゆれ・欠損の是正)を行う |
| データレイク | 構造化・半構造化・非構造化データを加工せずそのまま貯める | 使うときに構造を決める。DWH は入れる前に決める |
| OLAP | 多次元データを軸を変えながら対話的に分析する | ドリルダウン、スライシング、ダイシング |
| データマイニング | 大量データから隠れた規則や相関を見つけ出す | 「一緒に買われる組合せ」の発見が典型 |
これらを支える基盤として、大規模データを複数サーバへ分散して処理する Apache Hadoop(分散ファイルシステム HDFS)や Apache Spark、その上で SQL に近い問合せを実行する Apache Hive・Presto があります。データの意味・所在を管理するのがデータディクショナリや IRDS(情報資源辞書システム)で、開発・保守の情報まで一元管理する仕組みをリポジトリと呼びます。
名前だけ押さえておく用語
シラバス Ver.7.2 の用語例のうち、直近 10 年で単独出題の実績が無いものです。深追いは不要ですが、他の肢を消すのに使えるので「どの分野の語か」だけ結び付けておきます。
| 用語 | 押さえどころ |
|---|---|
| 代表的な製品名 | 関係データベースは MySQL・PostgreSQL・SQLite。NoSQL は Redis(キーバリュー型)、MongoDB・Apache CouchDB(ドキュメント指向型)、Apache Cassandra(列指向型)、Neo4j(グラフ型) |
| 物理データモデル | 論理データモデルを、特定の DBMS の格納形式に合わせて具体化したもの。設計は概念 → 論理 → 物理の順に進む |
| 副次索引・分割法 | 主キー以外の列に張る索引が副次索引。表を行・列で分けて配置する設計手法が分割法 |
| 配置モード・親子集合・親子集合順序 | 網型データベースで、レコードの格納位置と親子関係の並び順を指定する概念。バックマン線図とセットで登場する |
| 存在制約・インバーテッドファイル | 親レコードが実在しなければ子を置けないのが存在制約。値からレコード位置を引けるよう索引を反転させた編成がインバーテッドファイル(転置ファイル) |
| セマフォ方式 | 同時に使える資源の数を変数で数えて排他する方式。ロック方式と並ぶ同時実行制御の手段 |
| スキュー(skew) | 分散したデータやアクセスが特定のノード・キーに偏る状態。シャーディングのキー設計を誤ると起きる |
| コミットメント制御・コミットシーケンス | 複数の更新をまとめて確定・取消しする制御。分散環境で各サイトが確定していく順序がコミットシーケンス |
| ダンプファイル・世代管理 | バックアップとして書き出した複製がダンプファイル。複数世代を残して任意の時点へ戻せるようにする運用が世代管理 |
| BETWEEN・IN・LIKE | 範囲・列挙・パターン一致を表す述語。LIKE に渡す '東京%' のような文字列をパターン文字列といい、% が任意の文字列、_ が任意の 1 文字を表す |
| 相関名 | FROM 句で表に付ける別名。自己結合と相関副問合せでは、これが無いと同じ表の 2 つの役割を書き分けられない |
| モジュール言語・非カーソル操作 | SQL 文だけを別モジュールにまとめて親言語から呼ぶ方式がモジュール言語。結果が 1 行に決まる問合せをカーソルなしで変数へ受け取るのが非カーソル操作 |
| 分散問合せ・分散トランザクション・クライアントキャッシュ | 複数サイトの表にまたがる問合せと更新。利用者側に複製を持って通信を減らすのがクライアントキャッシュ |
| OSI-RDA プロトコル | 遠隔データベースアクセス(Remote Database Access)のための OSI 標準プロトコル |
| ブロックチェーン | 取引をブロックの連鎖として記録し改ざんを困難にする分散台帳。参加者が同じ内容に合意する手続きがコンセンサスアルゴリズム、確定が覆らない性質がファイナリティ |
| ビッグデータ・ストリーミングデータ | 量・種類・発生速度が従来の処理能力を超えるデータ群。絶えず流れ込む時系列データがストリーミングデータ |
| 構造化・半構造化・非構造化データ | 表形式が構造化、JSON や XML のように形が緩いものが半構造化、文書・画像・音声が非構造化 |
| ファクトデータベース・リファレンスデータベース | 数値や事実そのものを収めたものがファクト、所在や書誌を収めて一次情報へ導くものがリファレンス |
| 分散ファイルシステム | 複数ノードのディスクを 1 つのファイル空間に見せる仕組み。HDFS・Ceph・GlusterFS など |
| データベース応用システムの例 | 文書管理システム、営業支援システム(SFA)、企業会計システム、在庫管理システム |
ひっかけポイント
科目 A の誤答肢は、正解の記述を「1 段ずらす」「向きを逆にする」「別の用語の説明とすり替える」の 3 通りで作られます。本章で実際にその形が繰り返されている 5 か所を、作られ方ごと潰しておきます。
理解度チェック(科目 A 形式)
Q1. 3 層スキーマアーキテクチャにおける内部スキーマの説明として、適切なものはどれか。
- 業務全体の論理的なデータ構造を、特定の DBMS や記憶装置に依存しない形で定義する
- 利用者やアプリケーションごとに、必要な部分だけを切り出したデータの見え方を定義する
- データを記憶装置上にどう格納するかを、ファイル編成やインデックスとして定義する
- データ項目の名称と意味を組織で統一するための命名規約を定義する
正解: ウ 内部スキーマは記録媒体への格納方法を定める層で、インデックスの定義は内部スキーマ設計にあたります。ア は概念スキーマ、イ は外部スキーマ(ビュー)の説明です。エ はデータ項目標準化の話で、3 層スキーマのどの層でもありません。
Q2. 部門表(主キーは部門コード)と社員表(主キーは社員番号、部門コードを部門表への外部キーとして持ち、NULL は許さない)がある。この 2 つの関連を UML クラス図の多重度で表したものとして、適切なものはどれか。
- 部門 0..1 — 社員 1
- 部門 1 — 社員 0..*
- 部門 0..* — 社員 1..*
- 部門 1..* — 社員 1
正解: イ 他方の主キーを外部キーとして持つ側が「多」なので、部門が 1、社員が多です。社員の部門コードが NULL 不可なので社員から見た部門は必ず 1 件、部門から見た社員は 0 人でもあり得るので 0..* になります。ア と エ は 1 と多が逆で、ウ は多対多にしてしまっています。
Q3. 表「受講記録(社員番号, 講座コード, 受講日, 講座名, 講師名)」の主キーは 社員番号 + 講座コード である。講座名と講師名は講座コードだけで一意に決まり、受講日は主キー全体で決まる。この表はどの正規形か。
- 第 1 正規形
- 第 2 正規形
- 第 3 正規形
- ボイスコッド正規形
正解: ア 繰返し項目が無いので第 1 正規形は満たしますが、講座名・講師名が主キーの一部である講座コードだけで決まる部分関数従属が残っているため、第 2 正規形の条件を満たしません。イ・ウ・エ はいずれも判定を 1 段以上高く見積もった誤りです。
Q4. Q3 の受講記録表を第 3 正規形まで分解した結果として、適切なものはどれか。
- 受講記録(社員番号, 講座コード, 受講日, 講座名)、講座(講座コード, 講師名)
- 受講記録(社員番号, 講座コード, 受講日)、講座(講座コード, 講座名, 講師名)
- 受講記録(社員番号, 講座コード)、講座(講座コード, 講座名, 講師名)、受講日(社員番号, 受講日)
- 受講記録(社員番号, 受講日)、講座(講座コード, 講座名, 講師名)
正解: イ 講座コードだけで決まる講座名・講師名を講座表へ切り出せば部分関数従属が消え、残った受講日は主キー全体に完全関数従属し、非キー属性同士の推移的関数従属もありません。ア は講座名を元表に残しているため部分関数従属が消えていません。ウ は受講日を社員番号だけの表にしてしまい、いつどの講座を受けたかが失われます。エ は社員番号と講座コードの対応そのものが失われ、元の表に戻せません。
Q5. 部門表の部門コードを、社員表の部門コードが外部キーとして参照している。ON DELETE 句を指定していないとき、参照制約によって拒否される操作はどれか。
- 部門表に存在する部門コードを持つ行を、社員表に追加する
- どの社員行からも参照されていない部門の行を、部門表から削除する
- 社員行から参照されている部門の行を、部門表から削除する
- 社員表から任意の行を削除する
正解: ウ 削除すると、残る社員行の部門コードが参照先を失うため拒否されます。ア は参照先が実在するので許されます。イ は参照している子行が無いので許されます。エ は子側の削除であり、参照整合性は壊れません。
Q6. 関係 R と関係 S は和両立である。R ∩ S(共通部分)と同じ結果になる式はどれか。
- R ∪ (R − S)
- S − (R − S)
- (R ∪ S) − R
- R − (R − S)
正解: エ R から「R にしか無い部分(R − S)」を取り除けば、R と S の両方にある部分だけが残ります。ア は R そのものになります。イ は S から R−S を引いても S は減らないので S のままです。ウ は S − R、つまり S にしか無い部分になります。
Q7. 講座表に C01〜C06 の 6 行、受講表に(S01, C01)(S02, C01)(S01, C03)の 3 行が格納されている。SELECT 講座コード FROM 講座 A WHERE NOT EXISTS (SELECT 1 FROM 受講 B WHERE B.講座コード = A.講座コード) を実行した結果は何行か。
- 2
- 3
- 4
- 6
正解: ウ 内側は外側の別名 A を参照する相関副問合せで、外側 1 行ごとに評価されます。受講表に現れる講座コードは C01 と C03 の 2 種類なので、この 2 行は NOT EXISTS が偽で除外され、C02・C04・C05・C06 の 4 行が残ります。ア は受講表に現れる講座の数、イ は受講表の行数、エ は条件を無視した講座表の全行です。
Q8. B+ 木インデックスとハッシュインデックスの比較として、適切なものはどれか。
- B+ 木は完全一致検索にしか使えないが、ハッシュは範囲検索にも使える
- どちらも範囲検索に使えるが、B+ 木のほうが必ず記憶領域を多く必要とする
- ハッシュの探索回数はデータ件数に比例し、B+ 木は件数によらず常に 1 回である
- ハッシュは完全一致検索に向くが、範囲検索や整列には使えない
正解: エ ハッシュ関数は値の順序を保存しないため、完全一致でしか引けません。ア は両者の得意分野を逆転させた肢です。イ はハッシュが範囲検索に使えるとしている点が誤りです。ウ は探索コストの説明が逆で、B+ 木は木の高さに比例(およそ log に比例)し、ハッシュがほぼ 1 回です。
Q9. トランザクション T1 が、ある行に共有ロックを掛けている。このとき T2 が同じ行に対して要求しても待たされないロックはどれか。
- 共有ロックだけ
- 専有ロックだけ
- 共有ロックと専有ロックのいずれも
- どちらも要求できず必ず待たされる
正解: ア 両立するのは共有ロック同士だけです。読むだけなら複数のトランザクションが同時に行っても値が変わらないためです。イ とウ は、書き込みを伴う専有ロックが共有ロックと両立するとしている点が誤りです。エ は共有ロック同士まで待たせてしまい、同時実行性を不必要に下げる誤りです。
Q10. トランザクションの ACID 特性に含まれないものはどれか。
- 一貫性(Consistency)
- 原子性(Atomicity)
- 耐久性(Durability)
- 可用性(Availability)
正解: エ ACID は原子性・一貫性・独立性(Isolation)・耐久性の 4 つで、可用性は含まれません。ア・イ・ウ はいずれも ACID の構成要素です。頭文字の A を Availability と読み替えさせるのが出題側の狙いで、NoSQL の BASE にある Basically Available と混同させる形もあります。
Q11. ログとチェックポイントを用いる DBMS で、主記憶の内容が失われるシステム障害(ディスクは正常)から回復する。ロールフォワードの対象となるトランザクションはどれか。
- チェックポイントより前に開始し、チェックポイントより前にコミットしたもの
- チェックポイントより前に開始し、チェックポイントの後で障害発生前にコミットしたもの
- チェックポイントより後に開始し、障害発生時点でコミットしていないもの
- チェックポイントより前に開始し、障害発生時点でコミットしていないもの
正解: イ コミット済でありながら更新結果がディスクへ書き出されていない可能性があるのは、チェックポイント後にコミットしたものだけです。ア はチェックポイント時点でディスクへ反映済みなので回復不要です。ウ とエ は未コミットなので、更新前ログを使ったロールバックの対象です。
Q12. 取り扱う項目の構成が案件ごとに異なり、列をあらかじめ固定できないデータを、構造を変換せずに 1 件ずつそのまま格納したい。最も適した NoSQL の分類はどれか。
- キーバリュー型
- グラフ指向型
- ドキュメント指向型
- 列指向型(ワイドカラム)
正解: ウ ドキュメント指向型は JSON や XML の文書を 1 件として格納するので、項目構成が件ごとに違っても扱えます。ア は値の中身を問わない単純なキーと値の対で、項目ごとの検索には向きません。イ はノードとエッジのつながりを探索する用途です。エ は列単位に格納して大量データの一部の列を集計する用途で、いずれも列構成が不定であること自体への答えにはなりません。
Q13. ストアドプロシージャを用いる利点として、適切なものはどれか。
- 複数の SQL をサーバ側に登録しておき 1 回の呼出しで実行できるので、クライアントとサーバ間の通信量が減る
- 表への挿入・更新・削除を契機として、登録しておいた処理が自動的に起動される
- 実データを持たない仮想の表として、利用者に見せる列と行を限定できる
- 索引を用いずに表全体を走査するので、統計情報が古くても実行時間が変わらない
正解: ア サーバ内で一連の SQL がまとめて実行されるため、SQL 文と中間結果の往復が減ります。イ はトリガの説明で、ストアドプロシージャは CALL で明示的に呼び出します。ウ はビューの説明です。エ は利点ではなく、全表走査を強制すれば大きな表ほど遅くなります。
Q14. データマイニングの説明として、適切なものはどれか。
- 業務システムのデータを時系列に蓄積し、意思決定のための分析基盤として保持する
- 表記ゆれや欠損値を是正して、分析に使える形にデータを整える
- 多次元データの軸を対話的に切り替えながら、集計値を掘り下げて分析する
- 大量のデータを統計的手法などで解析し、そこに潜む規則性や相関を見つけ出す
正解: エ マイニングは「発見」がねらいで、購買データから一緒に買われる組合せを見つけるといった使い方が典型です。ア はデータウェアハウス、イ はデータクレンジング、ウ は OLAP の説明で、いずれも誤答肢の常連です。
まとめ
この章は「判定の手順を体に入れる」ことがそのまま得点になります。下の表は、科目 A で問われる形に絞った総まとめです。
| 論点 | 判定・要件の核 | 取り違えやすい相手 |
|---|---|---|
| 3 層スキーマ | 外部=利用者の見え方/概念=全体の論理構造/内部=格納方法 | 内部スキーマ設計=インデックス定義 |
| 多重度 | 他方の主キーを外部キーで持つ側が「多」。矢印は親から子へ | 向きの逆転、1 と 1..* の混同 |
| 正規形 | 第 2 ⇔ 部分関数従属なし/第 3 ⇔ 推移的関数従属なし | 1 段ずらし、非キー属性を残した分解 |
| 参照制約 | 拒否は「親に無い子の追加」と「参照されている親の削除」 | CASCADE・RESTRICT・SET NULL の取り違え |
| ビュー | 射影・選択だけなら更新可能。集約・GROUP BY・UNION は更新不可 | 集計を含むビューを更新可とする肢 |
| 評価順序 | FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY | WHERE と HAVING、列別名を使える句 |
| 結合 | 実績が無い側も残すなら外部結合。NULL は COALESCE で置換 | 内部結合で行が消えることの見落とし |
| 集合演算 | R ∩ S = R −(R − S)。和・差・共通は和両立が前提 | 差の向き、和と共通、直積との混同 |
| インデックス | B+ 木=範囲・前方一致・整列/ハッシュ=完全一致のみ | 得意分野の逆転、探索コストを件数比例とする肢 |
| ロック | 両立するのは共有ロック同士だけ。待ちグラフの閉路=デッドロック | 専有同士の両立、閉路に無い相手の巻き込み |
| ACID | 原子性・一貫性・独立性・耐久性の 4 つ | 可用性・信頼性の混入、BASE の A |
| 障害回復 | コミット済=ロールフォワード/未コミット=ロールバック/チェックポイント前に完了=回復不要 | RF と RB の入替え、媒体障害の手順との混同 |
| 2 相コミット | 第 1 相で可否を集め、第 2 相で確定。決定送信直前の障害が最も危険 | 第 1 相と第 2 相の入替え |
| NoSQL | KVS=キャッシュ/ドキュメント=項目不定/列指向=列の集計/グラフ=つながり | 4 分類の特徴の入替え、関係データベースの説明 |
- 科目 A は直近 10 年(19 回)で 93 問、1 回平均 4.9 問。上位 5 テーマ(正規化 8 回、ロールフォワード/ロールバック 6 回、参照制約 6 回、概念データモデル 6 回、インデックス 6 回)だけで 32 問を占めます
- 上位 15 テーマまで広げると 93 問中 66 問(約 71 %)。本章の表と図をひととおり言葉で説明できれば、目標の 4 問は届く範囲です
- 同一問題・同趣旨の再出題が多い分野です。図 9-3(正規化の分解)・図 9-4(参照制約)・図 9-7(B+ 木とハッシュ)・図 9-9(回復の判定)の 4 枚は、直前の見直しでそのまま使えます
次章では、この DBMS を利用者へ届ける通信基盤を扱います。第 10 章「ネットワーク」で、プロトコルの階層とアドレス設計を押さえてください。