データベース(正規化・SQL・トランザクション)
まず結論から
経営情報システムのデータベース分野は毎年出題される頻出エリアです。正規化の3段階(第1〜第3正規形)の判定方法、SQL基本構文の読み解き、ACID特性の穴埋めの3つを押さえれば、この分野は安定して得点できます。
1. 関係データベースの基本概念
関係データベース(RDB:Relational Database)はデータを「表(テーブル)」で管理します。
| 用語 | 意味 |
|---|---|
| テーブル | データを格納する表。Excelのシートに近いイメージ |
| フィールド(列) | 属性の種類。「商品名」「単価」など |
| レコード(行) | 1件のデータ |
| 主キー(PK) | レコードを一意に識別するフィールド。重複・NULLは不可 |
| 外部キー(FK) | 別テーブルの主キーを参照するフィールド。テーブル間を結ぶ |
erDiagram
注文 {
int 注文ID PK
int 顧客ID FK
date 注文日
}
顧客 {
int 顧客ID PK
string 顧客名
string 住所
}
注文明細 {
int 明細ID PK
int 注文ID FK
int 商品ID FK
int 数量
}
商品 {
int 商品ID PK
string 商品名
int 単価
}
顧客 ||--o{ 注文 : "1対多"
注文 ||--o{ 注文明細 : "1対多"
商品 ||--o{ 注文明細 : "1対多"
2. 正規化とは何か
正規化とは、データの冗長性(同じデータが複数箇所に重複している状態)と更新異常を排除するためにテーブルを整理する作業です。
更新異常には3種類あります。
- 挿入異常:一部データが揃っていないとレコードを挿入できない
- 削除異常:1件削除すると必要な情報まで消えてしまう
- 更新異常:1か所の変更を複数箇所に反映しなければならない
正規化はこれらを段階的に解消していきます。
3. 正規化の3段階
正規化のフロー
flowchart LR
UNF["非正規形\n繰り返しグループあり"]
F1["第1正規形\n繰り返し項目を排除"]
F2["第2正規形\n部分関数従属を排除"]
F3["第3正規形\n推移関数従属を排除"]
UNF -->|"繰り返しグループを\n独立行に展開"| F1
F1 -->|"主キーの一部にしか\n従属しない列を別テーブルへ"| F2
F2 -->|"主キー以外の列に\n従属する列を別テーブルへ"| F3
第1正規形:繰り返し項目の排除
1つのセルに複数の値が入っている「繰り返しグループ」を排除します。1セル1値が原則です。
Before(非正規形)
| 注文ID | 顧客名 | 商品名(繰り返し) |
|---|---|---|
| 001 | 田中 | りんご、みかん、ぶどう |
After(第1正規形)
| 注文ID | 顧客名 | 商品名 |
|---|---|---|
| 001 | 田中 | りんご |
| 001 | 田中 | みかん |
| 001 | 田中 | ぶどう |
第2正規形:部分関数従属の排除
部分関数従属とは、複合主キー(2列以上の組み合わせが主キー)の「一部の列だけ」に決まってしまう列が存在する状態です。
例:主キーが「注文ID+商品ID」のとき、「顧客名」は注文IDだけで決まる(商品IDは不要)。これが部分関数従属です。
graph LR
A["注文ID + 商品ID\n(複合主キー)"] -->|完全従属| B["数量"]
C["注文ID\n(主キーの一部)"] -->|部分従属| D["顧客名"]
→ 「顧客名」を含む行を別テーブル(注文テーブル)に分離します。
第3正規形:推移関数従属の排除
推移関数従属とは、「主キー → 列A → 列B」という連鎖で、列Bが間接的に主キーに従属している状態です。
例:顧客IDで「所属部署コード」が決まり、「所属部署コード」で「部署名」が決まる。
graph LR
A["顧客ID\n(主キー)"] --> B["部署コード"]
B --> C["部署名"]
→ 「部署名」は主キーに直接従属していないため、部署テーブルに分離します。
正規化の目的まとめ
| 正規形 | 排除する問題 | キーワード |
|---|---|---|
| 第1正規形 | 繰り返しグループ | 1セル1値 |
| 第2正規形 | 部分関数従属 | 複合主キーの一部への従属 |
| 第3正規形 | 推移関数従属 | 非キー列経由の間接従属 |
4. SQL基本構文
診断士試験では、SQLの完全な記述よりも「この構文は何をしているか」の読み解きが問われます。
SELECT文の基本構造
SELECT 列名1, 列名2 -- 取得する列を指定
FROM テーブル名 -- 対象テーブル
WHERE 条件 -- 絞り込み条件
GROUP BY 列名 -- グループ化
HAVING グループの条件 -- グループへの絞り込み
ORDER BY 列名 ASC/DESC -- 並び順(昇順/降順)
JOINの概念
複数テーブルを結合して1つの結果として取得します。
| 種類 | 意味 |
|---|---|
| INNER JOIN | 両テーブルに一致するレコードのみ取得 |
| LEFT JOIN | 左テーブルの全レコード+右テーブルの一致分 |
-- 注文テーブルと顧客テーブルを結合する例
SELECT 注文.注文ID, 顧客.顧客名, 注文.注文日
FROM 注文
INNER JOIN 顧客 ON 注文.顧客ID = 顧客.顧客ID
WHERE 注文日 >= '2024-01-01'
5. トランザクションのACID特性
トランザクションとは「一連の処理をひとまとまりとして扱う単位」です。銀行振込(A口座から引き落とし→B口座に入金)が典型例で、途中でシステム障害が起きても中途半端な状態にならないことが必要です。
ACID特性はこれを保証する4つの性質です。
| 特性 | 英語 | 意味 |
|---|---|---|
| 原子性 | Atomicity | トランザクション内の処理は「全て成功」か「全て失敗」の2択。中途半端な状態はない |
| 一貫性 | Consistency | トランザクション前後でデータの整合性が常に保たれる |
| 独立性 | Isolation | 複数のトランザクションが同時実行されても、互いに干渉しない |
| 永続性 | Durability | コミット(確定)されたデータは、その後のシステム障害でも失われない |
graph TB
subgraph トランザクション
T1["処理1: A口座から10万円引き落とし"]
T2["処理2: B口座に10万円入金"]
T1 --> T2
end
T2 -->|全て成功| COMMIT["COMMIT\n(確定)"]
T2 -->|どこかで失敗| ROLLBACK["ROLLBACK\n(全て取り消し)"]
style COMMIT fill:#d4edda
style ROLLBACK fill:#f8d7da
試験の引っかけ:「独立性=Integrity」は誤り。IntegrityはConsistency(一貫性)の文脈で使われることがある。独立性は「Isolation(アイソレーション)」です。
よくある疑問
Q. 第2正規形と第3正規形の違いが混乱する
区別のポイントは「何への従属か」です。
- 第2:主キーの「一部」への従属(複合主キーが前提)
- 第3:主キー「以外」の列への従属(間接的な従属)
「主キーの一部=第2、主キー以外の列を経由=第3」と覚えると整理できます。
Q. 正規化を進めるほど良いのか?
一概にそうではありません。正規化を進めるとテーブルが細かく分割され、データ取得時にJOINが増えて処理が重くなります。実務では性能とのバランスで「あえて非正規化する」ケースもあります(試験でも「非正規化のメリット」として問われることがあります)。
Q. ACIDのうち試験で特に問われる特性は?
原子性と永続性が頻出です。「障害が起きたとき、コミット済みのデータは消えない」が永続性、「途中でエラーが起きたら全部なかったことになる」が原子性です。
Q. COMMITとROLLBACKとは?
COMMITはトランザクションを「確定」する命令、ROLLBACKは「取り消し(開始前の状態に戻す)」命令です。原子性を実現するための仕組みです。
まとめ
| テーマ | 最重要ポイント |
|---|---|
| 主キー・外部キー | テーブル間の関係を結ぶ基本概念 |
| 第1正規形 | 繰り返し項目の排除(1セル1値) |
| 第2正規形 | 部分関数従属の排除(複合主キーの一部への従属) |
| 第3正規形 | 推移関数従属の排除(非キー列経由の間接従属) |
| SQL | SELECT-FROM-WHERE-JOIN-GROUP BYの読み解き |
| ACID | 原子性・一貫性・独立性・永続性の定義と具体例 |
正規化の問題は「この表は第何正規形か」「第3正規形に直すと表はいくつに分かれるか」という形式で頻出です。実際の表を見ながら従属関係の矢印を書いてみると理解が定着します。