第4章 データベース
この章のねらい 「データベース」は、経営情報システムの得点源の一丁目一番地です。とくに 正規化とSQLは、毎年のように出題される超・頻出テーマ。しかも、 用語の丸暗記ではなく「表を分解する手順」「SQL文を1行ずつ読む」といった、 やり方さえ身につければ確実に解ける"作業系"の問題が中心です。IT初心者の方でも、 手順どおりに進めれば必ず得点できるようになります。
過去問での出方:ほぼ毎年、データベースから2〜3問出ます。内訳は、 ①正規化(H19・H30・R02・R05・R06・R07…と常連)、②SQL文の実行結果 (SELECT・WHERE・JOIN・GROUP BY…)、③トランザクション/排他制御 (ACID特性・ロック・デッドロック)、④DBMSの用語(ストアドプロシージャ等)。 この章を固めれば、情報システムの合格ラインがぐっと近づきます。
4-0 この章の地図
データベースの学習は、「入れ物のかたち(テーブル)」→「きれいに整える(正規化)」 →「取り出す・操作する(SQL)」→「安全に同時利用する(トランザクション)」という 順に進みます。まず全体像をつかみましょう。
4-1 関係データベース … テーブル・行・列・主キー・外部キー・関係演算
│ (データの「入れ物」の基本ルール)
│
4-2 正規化 … 表を分解して重複・矛盾をなくす(★超頻出)
│ 非正規形→第1→第2→第3正規形
│
4-3 SQLの基礎 … データを取り出す言葉(★超頻出)
│ SELECT・WHERE・JOIN・GROUP BY・集計関数
│
4-4 トランザクション管理 … 複数人で同時に使っても壊れない仕組み
ACID特性・ロック・デッドロック・コミット
- 4-1・4-2は「設計」の話(どんな表を用意するか)
- 4-3は「利用」の話(用意した表からどう取り出すか)
- 4-4は「運用」の話(大勢で同時に使っても矛盾が起きないようにする)
順番に読めば、バラバラだった知識が1本の線でつながります。
4-1 関係データベース(リレーショナルデータベース)
そもそもデータベースとは
データベースとは、ひとことで言えば
「たくさんのデータを、あとで探しやすい・使いやすいように、 決まった形で整理して貯めておく箱」
です。そして、そのデータベースを管理する専用ソフトを DBMS(Database Management System=データベース管理システム)と呼びます。 私たちが直接データをいじるのではなく、このDBMSを通してデータを保存・検索・更新します。
関係データベースは「表(テーブル)」でできている
現在いちばん広く使われているのが、関係データベース(リレーショナルデータベース/RDB)です。 これは、データを表(テーブル)の集まりとして管理する方式です。エクセルの表を イメージすると分かりやすいでしょう。
┌── 列(カラム/属性・フィールド)
│ 「どんな項目か」を表す
▼
┌───────┬─────────┬──────┐
│ 顧客ID │ 氏名 │ 住所 │ ← 見出しの行
├───────┼─────────┼──────┤
│ C0001 │ 経済 一郎 │ 東京 │ ← 行(レコード/タプル・組)
├───────┼─────────┼──────┤ 「1件分のデータ」を表す
│ C0002 │ 政策 次郎 │ 大阪 │
└───────┴─────────┴──────┘
用語を整理しておきます(試験ではこの言い換えがそのまま問われます)。
| 表での呼び方 | 別名(試験で頻出) | 意味 |
|---|---|---|
| 表(テーブル) | 関係(リレーション) | データの入れ物ひとつ分 |
| 行 | レコード/タプル/組 | 1件分のデータ(例:顧客1人分) |
| 列 | カラム/属性/フィールド | データの項目(例:氏名、住所) |
💡 覚え方:行=ヨコ=1件のデータ、列=タテ=項目。 「タプル=行」「属性=列」という言い換えだけ押さえれば十分です。
主キー ― 行を1つに特定する「背番号」
表の中のどの1行かを、確実に1つだけ特定できる列(またはその組み合わせ)を 主キー(primary key)といいます。人でいえば「マイナンバー」「社員番号」のような、 重複しない・空欄にできない背番号です。
- 一意性:主キーの値は表の中で重複してはいけない(同じ顧客IDが2つあってはダメ)。
- 非NULL(空欄禁止):主キーは必ず値が入っていなければならない。
- 1つの列で足りないときは、複数列を組み合わせて主キーにします (これを複合キーと呼びます。例:「受注番号+枝番」で1行が決まる、など)。
外部キー ― 表と表をつなぐ「橋渡し」
外部キー(foreign key)とは、別の表の主キーを参照する列のことです。 表と表を関連づける(=リレーションを張る)ための"のりしろ"です。
【受注表】 【顧客表】
┌───────┬───────┐ ┌───────┬─────────┐
│受注番号│ 顧客ID │─────────▶│ 顧客ID │ 氏名 │
├───────┼───────┤ 外部キー ├───────┼─────────┤
│ 10001 │ C0001 │ が主キー │ C0001 │ 経済 一郎 │
│ 10002 │ C0002 │ を参照 │ C0002 │ 政策 次郎 │
└───────┴───────┘ └───────┴─────────┘
- 受注表の「顧客ID」は、顧客表の主キー「顧客ID」を指し示す外部キー。
- この仕組みのおかげで、受注表には顧客IDだけ持たせておき、 氏名・住所などは顧客表を見に行けばよい(=同じ情報を何度も書かずに済む)。
- 参照整合性:外部キーには、参照先に存在しない値を入れられない (実在しない顧客IDで受注を作れない)というルールがあります。
⚠️ 混同注意:主キーと外部キー - 主キー=その表の中で行を特定する「自分の背番号」 - 外部キー=他の表の主キーを指す「相手への参照」 「顧客ID」は、顧客表では主キー、受注表では外部キー――というように、 同じ列でも表が違えば役割が変わる点に注意します。
関係演算 ― 表から必要な部分を取り出す3つの操作
関係データベースでは、表に対して関係演算という操作を行い、欲しいデータを取り出します。 試験で押さえるべきは次の3つです。SQL(4-3)の土台になります。
| 演算 | 何をするか | イメージ |
|---|---|---|
| 選択(selection) | 条件に合う行(ヨコ)を抜き出す | 「住所が新宿の行だけ」=ヨコ方向で絞る |
| 射影(projection) | 必要な列(タテ)だけを抜き出す | 「氏名と住所の列だけ」=タテ方向で絞る |
| 結合(join) | 複数の表を、共通の列でつなげて1つの表にする | 受注表+顧客表を顧客IDでつなぐ |
● 選択(行を絞る) ● 射影(列を絞る)
┌──┬──┬──┐ ┌──┬──┬──┐
│ │ │ │←残す │██│ │██│
├──┼──┼──┤ │██│ │██│
│██│██│██│←消す │██│ │██│
└──┴──┴──┘ └──┴──┴──┘
ヨコ方向で選ぶ タテ方向で選ぶ
⚠️ 混同注意:選択と射影 - 選択=行(ヨコ)を絞る(WHERE で条件を付ける) - 射影=列(タテ)を絞る(SELECT で列名を指定する) 名前と方向が紛らわしい定番の引っかけです。「選択はヨコ・射影はタテ」で覚えましょう。
DBMSがしてくれること(用語チェック)
DBMS(データベース管理システム)は、単にデータを貯めるだけでなく、次のような機能を持ちます。 R05 第5問では、これらの用語の定義が正しく対応しているかが問われました。
| 用語 | ひとことで言うと |
|---|---|
| ストアドプロシージャ | よく使う一連の処理(SQLなど)を1つのプログラムにまとめてDBMSに登録したもの |
| トリガ | 表の更新などをきっかけに自動実行される処理 |
| インデックス(索引) | 検索を高速化する索引(本の巻末索引と同じ発想) |
| カーソル | 検索結果を1件ずつ順に読み進めるための仕組み |
| レプリケーション | データを複製して別の場所に同期しておく(複製・冗長化) |
| ロールフォワード | 障害復旧で、ログから更新を再適用して復旧する(→ 4-4で詳述) |
📝 過去問はこう出る(R05 第5問) DBMSの用語と定義の対応を問う問題。正解は 「ストアドプロシージャは、一連の処理を1つのプログラムとしてまとめてDBMSに格納したもの」。 引っかけは、用語と説明のすり替え:「トリガ」の説明として"結果を1件ずつ読む"(=実はカーソル)、 「インデックス」の説明として"コネクションを維持・再利用する"(=実はコネクションプーリング)など。 用語の名前と中身をペアで覚えておけば確実に解けます。 → R05 第5問
4-2 正規化 ★超頻出
正規化とは ― 表を分解して「重複」と「矛盾」をなくす
正規化(normalization)とは、ひとことで言えば
「1つの大きな表を、うまく複数の表に分解して、 データの重複や矛盾(更新不整合)が起きないように整えること」
です。なぜこれが必要なのか。まず、分解していない表で何が困るかを見ましょう。
正規化しないと起きる「更新不整合」
たとえば、受注のたびに顧客名や商品名まで全部1つの表に書き込むと、こうなります。
【ダメな例:全部を1つの表に詰め込む】
受注番号│顧客ID│顧客名 │商品コード│商品名 │単価
10001 │C001 │経済一郎 │ P101 │おにぎり │ 250
10002 │C001 │経済一郎 │ P201 │お茶 │ 100
10003 │C002 │政策次郎 │ P101 │おにぎり │ 250
この表には、次の3つの困りごと(更新不整合)が潜んでいます。
- ① 更新時異状:おにぎりの単価が変わったら、P101が出てくる全行を書き直す必要がある。 1か所でも直し忘れると、同じ商品なのに単価が違う――という矛盾が生じる。
- ② 挿入時異状:まだ1件も注文されていない新商品を登録したくても、 受注がないと行を作れない(受注番号が空欄になってしまう)。
- ③ 削除時異状:ある受注を削除したら、その商品の情報まで一緒に消えてしまう。
これらをまとめて更新不整合(更新時/挿入時/削除時の異状)と呼びます。 正規化は、この3つを防ぐために表を分解する作業です。
関数従属 ― 「Aが決まればBが決まる」関係
正規化を理解するカギが関数従属です。むずかしそうな言葉ですが、中身は単純で、
「ある列Aの値が決まれば、別の列Bの値が自動的に1つに決まる」
という関係のことです。これを「A → B」と書きます。
- 例:商品コード → 単価(商品コードが「P101」と決まれば、単価は「250」に一意に決まる)
- 例:顧客ID → 顧客名(顧客IDが決まれば顧客名が決まる)
正規化とは、この関数従属をたよりに「Aと、Aで決まるBは、まとめて別表にする」作業なのです。
正規化の3ステップ(第1→第2→第3正規形)
正規化は段階的に進めます。試験で問われるのは第3正規形までです。
非正規形(繰り返し項目がある)
│ ① 繰り返しをなくす(1マス1データにする)
▼
第1正規形
│ ② 部分関数従属をなくす(主キーの一部だけで決まる列を分離)
▼
第2正規形
│ ③ 推移的関数従属をなくす(キー以外→キー以外の従属を分離)
▼
第3正規形(完成)
各ステップを、ひとことで整理すると次のとおりです。
| 正規形 | やること | ひとことで |
|---|---|---|
| 第1正規形(1NF) | 繰り返し項目をなくし、1マスに1つの値にする | 「マスを単一値に」 |
| 第2正規形(2NF) | 部分関数従属を分離(複合キーの一部だけで決まる列を別表へ) | 「キーの一部で決まる列を出す」 |
| 第3正規形(3NF) | 推移的関数従属を分離(キー以外の列で決まる列を別表へ) | 「キー以外で決まる列を出す」 |
- 部分関数従属:主キーが複合キー(例:受注番号+商品コード)のとき、 その一部の列だけ(例:受注番号だけ)で決まってしまう列があること。
- 推移的関数従属:「主キー → 列X → 列Y」と、キー以外の列を経由して決まる関係 (例:受注番号 → 得意先コード → 得意先名)。
【手順つき例】受注管理表を第3正規形まで分解する
H30 第8問を題材に、実際に手を動かしてみましょう。次の1枚の表を分解します。
【元の表】受注ごとに全部を書き込んだもの
受注番号│月日│得意先コード│得意先名│商品コード│商品名 │販売数量│単価
(主キーは 受注番号+商品コード)
ステップ①:第1正規形の確認 → 各マスに値が1つずつ入っており、繰り返し項目はない。第1正規形はクリア。
ステップ②:部分関数従属を分離 → 第2正規形 主キーは「受注番号+商品コード」の複合キー。ここで、 - 受注番号 → 月日・得意先コード・得意先名(受注番号だけで決まる=部分関数従属) - 商品コード → 商品名・単価(商品コードだけで決まる=部分関数従属) これらを切り出します。
ステップ③:推移的関数従属を分離 → 第3正規形 - 得意先コード → 得意先名(キー以外を経由)→ 「得意先表」として独立 - 商品コード → 商品名・単価 → 「商品表」として独立
分解結果は、次の3つの表になります。
【受注表】 【得意先表】 【商品表】
受注番号│月日│ 得意先コード│得意先名 商品コード│商品名│単価
得意先コード│ (単価は商品ごとに一定)
商品コード│販売数量
こうして「受注表・得意先表・商品表」の3表に分割されました(H30 第8問の正解=3表)。
📝 過去問はこう出る(H30 第8問) 「第3正規形まで正規化するといくつの表に分割されるか」を問う問題。正解は3表 (受注表・得意先表・商品表)。4表・5表などは分割しすぎ。 「◯◯コード → ◯◯名」の従属を1組ずつ別表にする、と考えれば表の数を数えられます。 → H30 第8問
📝 過去問はこう出る(R05 第8問) 受注管理表が「どの正規形か」を判定させる問題。主キーは(受注番号, 枝番)の複合キー。 繰り返し項目はないので第1正規形は満たす。しかし、受注日・得意先コードは 「受注番号」だけで決まる(=部分関数従属)ため、第2正規形ではない。 よって正解は「第1正規形であるが、第2正規形ではない」。 部分関数従属が1つでもあれば第2正規形ではない、が判定のコツです。 → R05 第8問
💡 導出項目(計算で出る列)は持たない 「合計金額=販売数量×単価」のように、他の列から計算で求まる列は、 正規化では表に持たせず削除します(持つと、数量や単価を直したとき合計とズレる=冗長)。 R06 第7問では、この「合計金額を残す構造は不適切」という考え方が問われました。 → R06 第7問
4-3 SQLの基礎 ★超頻出
SQLとは ― データベースに命令する専用の言葉
SQL(エスキューエル)とは、関係データベースに対して 「このデータを取り出して」「この行を追加して」などと命令するための言語です。 試験でいちばん問われるのは、データを取り出す SELECT 文です。
SELECT文の基本形
データを取り出す SELECT 文は、次の"型"を覚えれば十分です。
SELECT ①取り出したい列(射影)
FROM ②どの表から
WHERE ③どの行を取り出すか(選択の条件)
GROUP BY ④どの列でグループにまとめるか
HAVING ⑤グループを絞る条件
ORDER BY ⑥どの列で並べ替えるか(ASC=昇順/DESC=降順)
- SELECT = 射影(列を選ぶ/4-1参照)、WHERE = 選択(行を絞る)。
- 上から下へ「どの表から → どの行を → まとめて → 並べる」と読むと理解しやすいです。
WHERE句 ― 行を絞り込む(LIKEによる文字列検索)
WHERE句には、行を絞る条件を書きます。数値の大小(> < =)のほか、
文字列のあいまい検索に使う LIKE が頻出です。
- LIKE '野菜%' … 「野菜」で始まる文字列(
%は0文字以上の任意の文字列を表すワイルドカード) - LIKE '%野菜%' … 「野菜」を含む文字列
- LIKE '%野菜' … 「野菜」で終わる文字列
LIKE '野菜%' にマッチする?
「野菜N産大根」 → ○(野菜で始まる)
「サラダ野菜」 → ×(野菜で始まらない。含んではいるが先頭ではない)
「ジュース野菜味」 → ×(同上)
📝 過去問はこう出る(H22 第12問)
WHERE 商品名 LIKE '野菜%' AND 単価>100の実行結果を問う問題。 ① 商品名が「野菜」で始まる行(「サラダ野菜」「ジュース野菜味」は先頭が野菜でないので除外)、 ② かつ単価>100 の両方を満たす行だけが残ります。%の位置(前・後・両側)と、AND条件の両立が急所。「含む」と「始まる」を取り違えると誤答します。 → H22 第12問
JOIN(結合)― 複数の表をつなぐ
複数の表を、共通の列(多くは外部キー)でつなげて1つの結果にするのが結合(JOIN)です。 2つの書き方があります(意味は同じ)。
【書き方A:FROMに2表・WHEREで結合条件】
SELECT 氏名, 店長名
FROM アルバイト, 店舗
WHERE アルバイト.店舗コード = 店舗.店舗コード ← ここが結合条件
AND 店舗所在地 = '新宿' ← ここは選択条件
読み方の手順は次のとおりです。
- 結合条件(
アルバイト.店舗コード = 店舗.店舗コード)で2表を1つに合体させる。 - 選択条件(
店舗所在地='新宿' AND 年間給与支給額<800000)で行を絞る。 - SELECT の列(氏名・店長名など)だけを取り出す(射影)。
📝 過去問はこう出る(H30 第4問) 「アルバイト表」と「店舗表」を店舗コードで結合し、
店舗所在地='新宿'かつ年間給与支給額<800000の行を取り出す問題。手順は①結合 → ②条件で絞る → ③列を取り出す。 引っかけは境界値:<800000は「800000を含まない」ので、給与ちょうど800000の人は除外。 「〜未満(<)」と「〜以下(<=)」の違いが正誤を分けます。 → H30 第4問
内部結合と外部結合の違いも押さえましょう。
| 結合の種類 | どんな行を残すか |
|---|---|
| 内部結合(INNER JOIN) | 両方の表で条件が一致した行だけ残す |
| 左外部結合(LEFT OUTER JOIN) | 左の表の全行を残し、右に相手がなければ空欄(NULL)で埋める |
| 右外部結合(RIGHT OUTER JOIN) | 右の表の全行を残す |
📝 過去問はこう出る(R07 第12問) 「登録ユーザ表」と「商品登録管理表」を結合するが、商品登録をしていない顧客も結果に残したい、 という設定。全ユーザを残すにはLEFT OUTER JOINが必要(INNER JOINだと登録なしの人が消える)。 ※この問題は選択肢のGROUP BY句がいずれも不備で「全員正解」となりましたが、 「相手がいない行も残すなら外部結合」という考え方はそのまま頻出です。 → R07 第12問
GROUP BYと集計関数 ― グループごとに合計・件数を出す
「担当者ごとの売上合計」「商品ごとの販売件数」のように、 グループにまとめて集計したいときは GROUP BY と集計関数を使います。
主な集計関数は次のとおりです。
| 集計関数 | 何を計算するか |
|---|---|
| SUM(列) | 合計 |
| COUNT(*) | 件数(行数) |
| AVG(列) | 平均 |
| MAX(列) / MIN(列) | 最大 / 最小 |
そして、グループ化した結果をさらに絞り込む条件は HAVING に書きます。
⚠️ 混同注意:WHERE と HAVING - WHERE=グループ化する前に、個々の行を絞る条件 - HAVING=グループ化した後に、集計結果(グループ)を絞る条件 「SUM(個数)>=3 のグループだけ」のように、集計値で絞るときは HAVING。ここは頻出の区別です。
GROUP BY の読み方を、GROUP BY 担当者コード, 製品名 を例に手順化します。
SELECT 担当者コード, 製品名, SUM(個数)
FROM 販売履歴表
GROUP BY 担当者コード, 製品名
HAVING SUM(個数) >= 3 ← 合計3以上のグループだけ残す
手順:
① 担当者コード×製品名の組ごとに行をまとめる
② 各グループの個数を SUM で合計する
③ 合計が3以上のグループだけ HAVING で残す
④ 担当者コード・製品名・合計 の3列を表示
📝 過去問はこう出る(H23 第8問) 上の SQL の実行結果を選ぶ問題。担当者コード×製品名でまとめて個数を合計し、 HAVING で合計3以上のグループだけを残します(例:「E102・エアコン=3」「P101・電池=10」は残り、 「E103・テレビ=2」は除外)。表示列は GROUP BY で指定した列+集計値 になる点も急所。 「担当者コードでグループ化していない結果」などが引っかけです。 → H23 第8問
ORDER BY と自己結合(発展)
- ORDER BY 列 DESC … 指定列で降順(大きい順)に並べる。ASCなら昇順(省略時は昇順)。
- 自己結合 … 同じ表を2回使って結合する高度なテクニック。「同じ取引で一緒に買われた商品の組」 を求める併売分析(バスケット分析)などで使います。
📝 過去問はこう出る(R05 第9問) 「同じ取引の中で買われた2商品の組み合わせ件数」を求める、自己結合のSQLの穴埋め問題。 ポイントは2つ。①同じ取引でまとめるため
A.取引ID = B.取引IDで結合、 ②A.商品ID < B.商品IDとすることで、同じ商品同士の組や(X,Y)と(Y,X)の重複を除く。 さらに件数の多い順に並べるためORDER BY 件数 DESC。 「< で一方向だけ残す」という発想が併売分析SQLの定番です。 → R05 第9問
4-4 トランザクション管理
トランザクションとは ― 「まとめて全部か、全部なしか」の処理のかたまり
トランザクションとは、
「業務上、ひとまとまりとして扱う必要がある一連の処理」
のことです。有名な例が銀行の振込です。
【振込トランザクション】
⑴ Aさんの口座残高から 1万円 引く ┐
├─ この2つは「まとめて1つ」でなければならない
⑵ Bさんの口座残高に 1万円 足す ┘
もし⑴だけ成功して⑵が失敗したら、Aさんのお金だけ消えるという大事故になります。 そこで、「全部成功したら反映、途中で失敗したら全部なかったことにする」という オール・オア・ナッシングの扱いが必要になります。この考え方を保証するのが、次のACID特性です。
ACID特性 ― トランザクションが満たすべき4つの性質
トランザクションが安全であるために満たすべき4条件を、頭文字をとってACID特性と呼びます。 R02 第7問でその定義が問われました。
| 特性 | 読み | 意味(ひとことで) |
|---|---|---|
| A:原子性(Atomicity) | げんしせい | 全部実行するか、全部取り消すか(All or Nothing)。中途半端はなし |
| C:一貫性(Consistency) | いっかんせい | 処理の前後でデータの整合性ルールが保たれる(残高がマイナスにならない等) |
| I:独立性(Isolation) | どくりつせい | 複数同時に実行しても、1つずつ順に実行したのと同じ結果になる(隔離性ともいう) |
| D:耐久性(Durability) | たいきゅうせい | いったん完了した結果は、障害が起きても失われない(永続性) |
⚠️ 混同注意:一貫性と独立性のすり替え 試験では、この4つの言葉と説明を入れ替えた選択肢が定番の引っかけです。 - 「同時実行しても逐次実行と同じ結果」=独立性(Isolation)(一貫性ではない) - 「障害からログで復旧を保証」=耐久性(Durability)(独立性ではない) 言葉と中身をペアで丸暗記しておきましょう。
📝 過去問はこう出る(R02 第7問) ACID特性の各語と定義の対応を問う問題。正解は 「トランザクションを構成する全ての処理が正常終了したときだけ反映する=原子性(Atomicity)」。 「ログで異常発生前に復旧=独立性」「逐次と同時で結果が同じ=一貫性」はいずれも言葉のすり替えでバツ (前者は本来は耐久性、後者は本来は独立性の説明)。 → R02 第7問
コミットとロールバック
トランザクションの結末は、次の2つのどちらかです。
- コミット(commit):処理が全部うまくいったので、変更を確定してデータベースに反映する。
- ロールバック(rollback):途中で失敗したので、変更を全部取り消して開始前の状態に戻す。
障害復旧では、ログ(変更の記録)を使って次の2方向の回復を行います。
- ロールフォワード(前進復旧):完了済みトランザクションの更新をログから再適用して復旧する (バックアップ以降の更新をやり直す)。
- ロールバック(後退復旧):未完了だったトランザクションの更新を取り消して整合性を回復する。
排他制御(同時実行制御)― 同時アクセスから守る
大勢が同時に同じデータを触ると、片方の更新が消えるなどの問題が起きます。これを防ぐのが 排他制御(同時実行制御)です。H24 第9問では、次の3方式が穴埋めで問われました。
| 方式 | やり方 | 特徴・注意点 |
|---|---|---|
| ① ロック方式 | 処理対象のデータにロック(鍵)をかけ、解除まで他の処理を待たせる | 確実だがデッドロックが起きうる |
| ② タイムスタンプ方式 | 読み書きの時刻を記録し、監視しあいながら処理 | 競合が多いと取り消しが増え実用性低下(楽観的制御) |
| ③ 楽観的制御(検証方式) | データを作業領域(キャッシュ)に読み込んで処理し、書き戻す際に時刻で他の更新がないか確認 | 競合が少ない前提だと効率的 |
ロックの種類
ロックには、用途に応じて2種類あります。
- 共有ロック(読み取りロック):読むだけなら複数の処理が同時にかけられる。 他者の読み取りは許すが、書き込みは待たせる。
- 専有ロック(排他ロック・書き込みロック):書き込むときにかける。 他者の読み取りも書き込みも待たせる(1つの処理が独占する)。
デッドロック ― お互いが相手のロック解除を待ち続ける
デッドロックとは、複数の処理が互いに相手が持つロックの解除を待ち合って、 どちらも先へ進めなくなる状態です。
処理A:資源1をロック済 → 資源2が欲しい(Bが持っている…待つ)
処理B:資源2をロック済 → 資源1が欲しい(Aが持っている…待つ)
↓
お互いに永遠に待ち続ける = デッドロック(膠着状態)
- 対策:ロックをかける順番を全体で統一する、タイムアウトで片方を強制的に打ち切る、など。
⚠️ 混同注意:デッドロックとセマフォ H24 第9問の引っかけは、空欄に「セマフォ」を入れさせるもの。ロック方式で発生する 「進めなくなる問題」はデッドロックであって、セマフォではありません(セマフォは資源数を管理する 別概念)。ロック → デッドロックの組み合わせで覚えましょう。
📝 過去問はこう出る(H24 第9問) 排他制御3方式(①ロック方式、②タイムスタンプ方式、③楽観的制御)の穴埋め。正解の組は A:ロック/B:デッドロック/C:時刻/D:キャッシュ領域。 ①でかけるのはロック、そこで起きる問題はデッドロック、②で監視するのは時刻(タイムスタンプ)、 ③で読み込む先はキャッシュ領域(作業領域)。用語のペアを覚えていれば正解できます。 → H24 第9問
この章のまとめ(試験直前チェック)
- ☐ 関係DBは表(テーブル)の集まり。行=レコード・タプル、列=属性・フィールド
- ☐ 主キー=行を一意に特定(重複×・空欄×)。1列で足りなければ複合キー
- ☐ 外部キー=他表の主キーを参照する列(表と表をつなぐ/参照整合性)
- ☐ 関係演算:選択=行(ヨコ)を絞る、射影=列(タテ)を絞る、結合=表をつなぐ
- ☐ 正規化=表を分解して重複・更新不整合(更新/挿入/削除の異状)を防ぐ
- ☐ 関数従属 A→B=Aが決まればBが1つに決まる関係
- ☐ 第1正規形=1マス1値/第2正規形=部分関数従属を排除/第3正規形=推移的関数従属を排除
- ☐ 部分関数従属が1つでもあれば第2正規形ではない(R05 第8問)
- ☐ 「◯◯コード→◯◯名」を1組ずつ別表に(H30 第8問は3表に分割)
- ☐ 計算で求まる導出項目(合計金額など)は表に持たない(R06 第7問)
- ☐ SELECT=射影、WHERE=選択。
LIKE '野菜%'=「野菜で始まる」(%の位置に注意) - ☐ 境界値:
<800000は800000を含まない(未満と以下を区別) - ☐ GROUP BY+集計関数(SUM/COUNT/AVG/MAX/MIN)でグループ集計
- ☐ WHERE=行を絞る(集計前)/HAVING=集計結果を絞る(集計後)
- ☐ 相手がいない行も残すなら外部結合(LEFT/RIGHT OUTER JOIN)、一致行だけなら内部結合
- ☐ トランザクション=まとめて全部か全部なしか。コミット=確定/ロールバック=取消
- ☐ ACID:原子性(全部or無)・一貫性(整合性維持)・独立性(逐次と同結果)・耐久性(障害でも残る)
- ☐ 排他制御:ロック方式(→デッドロック注意)/タイムスタンプ方式/楽観的制御
- ☐ デッドロック=互いに相手のロック解除を待ち合う膠着状態
この章に対応する主な過去問
| 年度・問 | 論点 | リンク |
|---|---|---|
| R05 第5問 | DBMSの機能(ストアドプロシージャ等) | 問題 |
| R07 第12問 | リレーショナルDB(表設計・外部結合) | 問題 |
| R05 第8問 | 受注管理表の正規形判定(第2正規形でない) | 問題 |
| H30 第8問 | 第3正規形への正規化(3表に分割) | 問題 |
| R06 第7問 | 正規化(導出項目の排除) | 問題 |
| H22 第12問 | SQL(WHERE・LIKEによる文字列検索) | 問題 |
| H30 第4問 | SQL(表の結合と条件抽出) | 問題 |
| H23 第8問 | SQL(GROUP BY・HAVING・集計) | 問題 |
| R05 第9問 | SQL(自己結合による併売分析) | 問題 |
| R02 第7問 | トランザクション処理(ACID特性) | 問題 |
| H24 第9問 | 排他制御・同時実行制御(ロック/デッドロック) | 問題 |
次章予告 ▶ 第5章「通信ネットワーク」 データベースが「データを貯める・取り出す」仕組みだったのに対し、次章では データをやり取りする仕組みを学びます。LAN/WAN、TCP/IP、IPアドレスとサブネット、 プロトコル、そして頻出の稼働率計算まで。ネットワークも計算・手順で得点できる分野です。