最終更新日:2026年8月28日
fe fe-technology database
まず結論
データベース正規化とは、データの重複を減らし、更新・挿入・削除のときに起こる不整合を防ぐために、表を適切に分ける考え方です。
FE試験では、まず第3正規形までを判断できれば十分です。
第1正規形
→ 1つのセルに1つの値
第2正規形
→ 複合主キーの一部だけで決まる項目を分ける
第3正規形
→ 主キー以外を経由して決まる項目を分ける
正規化の目的は、表を細かくすることではなく、重複による更新時異状を防ぐことです。
直感的な説明
次の注文表を考えます。
| 注文番号 | 顧客番号 | 顧客名 | 商品番号 | 商品名 |
|---|---|---|---|---|
| 1 | C01 | 山田商事 | P01 | 商品A |
| 2 | C01 | 山田商事 | P02 | 商品B |
| 3 | C01 | 山田商事 | P03 | 商品C |
顧客名や商品名が何度も保存されています。
顧客名が変わったとき、すべての行を直さなければなりません。1行だけ更新し忘れると、同じ顧客番号なのに顧客名が異なる状態になります。
そこで、注文表・顧客表・商品表へ分けます。
注文表:注文番号、顧客番号、商品番号
顧客表:顧客番号、顧客名
商品表:商品番号、商品名
こうすれば、顧客名は顧客表の1か所だけ更新すれば済みます。
ここで、顧客番号は注文表から消しません。
顧客番号は、分けた注文表と顧客表をつなぐために必要だからです。
注文表.顧客番号
↓
顧客表.顧客番号
FE試験では、「別表へ移す情報」と「表同士をつなぐキー」を区別することが重要です。
定義・仕組み
正規化の中心は、一つの事実を一つの場所で管理することです。
正規化によって、次の更新時異状を減らせます。
| 異状 | 内容 |
|---|---|
| 更新異状 | 同じ情報を複数箇所で直す必要があり、更新漏れで不整合が起きる |
| 挿入異状 | 別の情報がないと、登録したい情報を追加できない |
| 削除異状 | 行を削除すると、残したい情報まで失われる |
第1正規形
1つの項目に1つの値だけを入れる状態です。
電話番号:090-xxxx、080-xxxx
のように1セルへ複数値が入っている場合は、第1正規形ではありません。
判断ワードは、繰返し項目・複数値・原子値・1セル1値です。
第2正規形
複合主キーの一部だけに依存する属性を分離します。
主キーが、
注文番号 + 商品番号
で、商品名が商品番号だけで決まるなら、次の関係があります。
商品番号 → 商品名
これを部分関数従属といいます。商品番号と商品名を商品表へ分けることで、第2正規形になります。
第3正規形
主キー以外の属性を経由して決まる属性を分離します。
社員番号 → 部門番号 → 部門名
部門名は、社員番号から直接ではなく、部門番号を経由して決まっています。これを推移的関数従属といいます。
部門番号と部門名を部門表へ分けることで、第3正規形になります。
このテーマは、基本情報技術者試験の「データベース」「データベース設計」と関係します。公式の出題範囲やシラバスは、IPA:基本情報技術者試験から確認できます。
科目Aでどう出る?
| 問題文・選択肢の表現 | 判断 |
|---|---|
| 1つのセルに複数の値がある | 第1正規形を疑う |
| 複合主キーの一部だけで属性が決まる | 第2正規形を疑う |
| 主キー以外の属性を経由して決まる | 第3正規形を疑う |
| 冗長性を減らして更新時異状を防ぐ | 正規化の目的 |
| 検索性能のために重複を持たせる | 非正規化を疑う |
「第3正規形まで正規化する目的」を問われた場合は、次の流れで判断します。
冗長性を減らす
↓
更新時異状を防ぐ
一方、次の説明は外します。
- 必ず処理を高速化する
- 整合性制約を不要にする
- ロック待ちをなくす
- 格納容量の削減だけを目的とする
正規化問題を解く順番
FE試験では、正規化後の表を選ぶ問題もあります。
このタイプは、いきなり完成形を考えるより、第1正規形 → 第2正規形 → 第3正規形の順に、何によって項目が決まるかを確認すると整理しやすくなります。
① 繰返し項目を探す
② 1行を特定する主キーを決める
③ 複合主キーなら、片方だけで決まる項目を探す
④ 主キー以外の項目から決まる項目を探す
例えば、1枚の伝票に複数の商品が記録されるデータを考えます。
伝票番号
日付
顧客コード
顧客名
住所
商品コード
単位
数量
単価
① 繰返し項目をなくす
1枚の伝票に商品1、商品2、商品3……という繰返しがあるなら、まず商品ごとに行を分けます。
伝票123 ─ 商品A
伝票123 ─ 商品B
伝票123 ─ 商品C
この時点では、同じ伝票番号を持つ行が複数あります。
そのため1行を特定するには、例えば次の複合主キーが必要です。
伝票番号 + 商品コード
第1正規化では、繰返しをなくした結果、主キーが何になるかまで確認すると次へ進みやすくなります。
② 複合主キーの一部だけで決まる項目を探す
次に、複合主キーの全部を使わなくても決まる項目を探します。
伝票番号
↓
日付
顧客コード
顧客名
住所
商品コード
↓
単位
単価
このように、複合主キーの片方だけで決まる項目があります。
これが部分関数従属です。
第2正規化では、これらを別表へ分けます。
伝票表
伝票番号|日付|顧客コード|顧客名|住所
明細表
伝票番号|商品コード|数量
商品表
商品コード|単位|単価
ここでの判断は、
「主キーが2項目なら、片方だけで決まるものはないか?」
です。
③ 主キー以外から決まる項目を探す
第2正規化後の伝票表をもう一度見ます。
伝票番号
↓
顧客コード
↓
顧客名・住所
顧客名と住所は、伝票番号そのものではなく、顧客コードによって決まる情報です。
つまり、主キー以外の項目を経由して値が決まっています。
これが推移的関数従属です。
そこで第3正規化では、顧客情報も別表へ分けます。
伝票表
伝票番号|日付|顧客コード
顧客表
顧客コード|顧客名|住所
明細表
伝票番号|商品コード|数量
商品表
商品コード|単位|単価
試験では、第2正規形と第3正規形を次のように切り分けます。
第2正規形
→ 主キーの「一部」で決まるものを探す
第3正規形
→ 主キー「以外」から決まるものを探す
「何表に分ければよいか」を暗記するより、矢印で「Aが決まればBも決まる」と書いてみる方が、別の表が出題されても対応しやすくなります。
第3正規化で「両方の表に残す属性」を選ぶ
正規化問題では、表を分けたあとにどの属性を両方の表に残すかを問われることがあります。
例えば、次のような受注データを考えます。
受注表
注文番号
注文年月日
顧客ID
顧客名
顧客住所
品目
数量
送付先
支払方法
受注金額
注文番号が主キーで、次の関係があるとします。
注文番号 → 顧客ID → 顧客名・顧客住所
顧客名と顧客住所は、注文番号ではなく顧客IDによって決まっています。
そこで、第3正規化では顧客情報を別表へ分けます。
注文表
注文番号|注文年月日|顧客ID|品目|数量|送付先|支払方法|受注金額
顧客表
顧客ID|顧客名|顧客住所
ここで重要なのは、顧客IDは注文表にも残すことです。
顧客IDまで注文表から消してしまうと、どの注文がどの顧客のものか分からなくなります。
注文表.顧客ID
↓
顧客表.顧客ID
顧客表では顧客IDが主キーになり、注文表では顧客表を参照する外部キーになります。
試験では、次のように考えると選択肢を切りやすくなります。
顧客名・顧客住所
→ 重複を減らすため顧客表へ移す
顧客ID
→ 表同士をつなぐため両方に残す
Keep the key that links the tables.
表同士をつなぐキーは残す。
「分離する情報」と「関連付けるキー」は役割が違う、と整理しておきましょう。
関数従属図から表を選ぶときの判断手順
問題によっては、項目同士の関係が矢印で示され、正規化後の表の組合せを選ぶ形式があります。
このときは、矢印の数ではなく、矢印の出発点が主キーのどこにあるかを見ます。
例えば、主キーが (A, B) で、次の関係だけが示されているとします。
B → F
F は複合主キー全体 (A, B) ではなく、主キーの一部 B だけで決まります。
(A, B) が主キー
↓
B だけで F が決まる
↓
部分関数従属
↓
第2正規化で分離
したがって、表は次のように分けます。
(A, B, C, D, E)
(B, F)
ここで重要なのは、「第3正規形まで正規化する」と書かれていても、必ず3回表を分けるわけではないことです。
第2正規化で部分関数従属を取り除いたあと、
C → D
D → E
のような「主キー以外の項目から別の項目が決まる関係」がなければ、その時点で第3正規形の条件も満たします。
試験中は、次の順番で確認すると判断しやすくなります。
① 主キーを確認する
② 矢印の出発点を見る
③ 主キーの一部から出ている → 第2正規化
④ 主キー以外から出ている → 第3正規化
⑤ 示されていない依存関係を勝手に追加しない
どんな場面で使う?
- 顧客情報や商品情報を一元管理する
- 注文データの重複を減らす
- 更新漏れによる不整合を防ぐ
- データベース設計を見直す
正規化は、データの整合性を保ちやすくするための設計です。
よくある誤解・混同
正規化すると必ず高速になる
表を分けると結合処理が増えるため、読取り性能が下がる場合もあります。
検索を速くする仕組みとの違いまで整理したい場合は、インデックスとは?検索を速くするデータベースの索引も確認すると、役割を切り分けやすくなります。
表を多く分けるほどよい
必要以上に分けることが目的ではありません。重複や更新時異状を防ぐために分けます。
別表に移す情報は、元の表から全部消す
顧客名や顧客住所のような重複情報は別表へ移しますが、顧客IDのように表同士をつなぐキーは元の表にも残します。
顧客名・顧客住所 → 顧客表へ移す
顧客ID → 顧客表と注文表の両方に残す
「別表へ移す」と「元の表から完全に消す」は同じ意味ではありません。
第2正規形は主キーが1項目でも必ず問題になる
部分関数従属は、複合主キーの一部だけに依存する関係です。主キーが1項目なら、この形の部分関数従属は発生しません。
第2正規形と第3正規形が混ざる
迷ったら「何が決定元か」を見ます。
複合主キーの一部 → 第2正規形
主キーではない項目 → 第3正規形
例えば、
商品コード → 単価
が複合主キーの一部なら第2正規形の話です。
一方、
顧客コード → 顧客名
のように主キー以外の項目から決まるなら、第3正規形で分けます。
正規化と非正規化は反対なので、非正規化は誤り
非正規化は、性能上の理由などで意図的に重複を持たせる設計です。目的と影響を理解して行います。
正規化によって更新・追加・削除時の不整合がなぜ減るのかまで確認したい場合は、SG:正規化とは?データの重複を減らして整合性を保つ考え方も参考になります。
まとめ(試験直前用)
- 正規化の目的は、冗長性を減らして更新時異状を防ぐこと
- 第1正規形は繰返しをなくし、1セル1値にする
- 第2正規形は複合主キーの一部だけで決まる項目を分離する
- 第3正規形は主キー以外の項目から決まる項目を分離する
- 表問題では「繰返し → 主キー → 主キーの一部 → 主キー以外」の順で確認する
- 第3正規化で表を分けても、表同士をつなぐIDは両方に残す
- 関数従属図では、矢印の出発点が「主キーの一部」か「主キー以外」かを見る
- 正規化しても必ず高速になるわけではない