コンテンツにスキップ

データの正規化

データベースでは、データを「表(テーブル)」に格納して管理します。しかし、何も考えずにすべての情報を1つの表にまとめてしまうと、同じデータが何度も登場したり、データの書き換え時に矛盾が生じたりする問題が起こります。

正規化とは、こうしたデータの重複や不整合が発生しないように、1つの表を複数の表に分割して整理する作業のことです。正規化を行うことで、データベースの品質を高く保ち、効率的にデータを管理できるようになります。

試験で出るポイント

「データの重複及び不整合が発生しないように複数の表に分ける作業」を何と呼ぶか、という問題が頻出です。答えは正規化です。この定義はそのまま覚えておきましょう。

正規化しないとどうなるか ── 具体例で理解する

Section titled “正規化しないとどうなるか ── 具体例で理解する”

正規化がなぜ必要なのか、具体例で見てみましょう。ある店舗の受注データを、1つの表にまとめた場合を考えます。

正規化していない受注表:

受注番号発注者名商品番号商品名単価個数
001田中太郎A10ノートPC80,0002
001田中太郎A20マウス2,0003
002鈴木花子A10ノートPC80,0001
003佐藤一郎A20マウス2,0005

この表には、次のような問題が潜んでいます。

更新異常(データの不整合):「ノートPC」の単価が90,000円に変わったとします。受注番号001と002の両方を書き換えなければなりません。もし片方だけ更新して、もう片方を更新し忘れると、同じ商品なのに異なる単価が存在してしまいます。これがデータの不整合です。

挿入異常(データを追加できない):新しい商品「キーボード(商品番号A30、単価5,000円)」を登録したいとします。しかし、この表では受注がないと商品情報を登録できません。受注番号や発注者名の欄が空になってしまうからです。

削除異常(データが消えてしまう):受注番号003のデータを削除すると、「佐藤一郎がマウスを5個注文した」という受注情報だけでなく、佐藤一郎という発注者の情報自体も一緒に消えてしまいます。

このように、1つの表に異なる種類の情報(受注の情報と商品の情報)を混在させると、さまざまな問題が発生します。

正規化の基本的な考え方 ── 表を分割する

Section titled “正規化の基本的な考え方 ── 表を分割する”

正規化の基本は、関連するデータごとに表を分割し、それぞれの表が1つのテーマだけを扱うようにすることです。

先ほどの受注表を正規化すると、次のように分割できます。

受注表:

受注番号発注者名商品番号個数
001田中太郎A102
001田中太郎A203
002鈴木花子A101
003佐藤一郎A205

商品表:

商品番号商品名単価
A10ノートPC80,000
A20マウス2,000

受注表には「誰が何をいくつ注文したか」という受注に関する情報だけを、商品表には「商品の名前と単価」という商品に関する情報だけを格納しています。2つの表は商品番号という共通の項目で結びついており、必要なときに組み合わせて元の情報を復元できます。

この分割によって、先ほどの問題はすべて解消されます。

  • 更新異常の解消:商品の単価を変更するときは、商品表の1か所を書き換えるだけで済みます
  • 挿入異常の解消:新商品は商品表に追加するだけで登録でき、受注がなくても問題ありません
  • 削除異常の解消:受注データを削除しても、商品の情報は商品表に残り続けます

試験で出るポイント

過去問では「受注データを正規化して分割するとどのような表になるか」を問う問題が出題されています。「受注に関する情報」と「商品に関する情報」を分けるという考え方を理解しておきましょう。

冗長なデータの排除 ── 導出できるデータは持たない

Section titled “冗長なデータの排除 ── 導出できるデータは持たない”

正規化では、表を分割するだけでなく、他の項目から計算して求められる(導出できる)データを表に持たないことも重要です。

たとえば、会員管理の表に次のような項目があったとします。

会員番号会員名生年月日現在の満年齢
M001山田太郎1990-05-1535
M002佐藤花子2000-11-2025

この表の「現在の満年齢」は、「生年月日」と「今日の日付」から計算できます。つまり、冗長なデータ(なくても求められるデータ)です。このような項目を表に持っていると、時間が経つにつれて実際の年齢とずれてしまい、データの不整合が発生します。

正規化の考え方では、導出可能な項目は表から取り除き、必要なときにその都度計算して求めるようにします。

試験で出るポイント

「他の項目から導出できる冗長な項目はどれか」という形式の問題が出題されます。「生年月日」があれば「満年齢」は計算で求められるので、満年齢が冗長な項目です。同様に、「単価」と「個数」があれば「金額」は導出できるため冗長です。

正規化がうまくできたかどうかは、次の点で確認できます。

  • 同じ情報が複数の行に繰り返し登場していないか:たとえば商品名や単価が何度も現れている場合、まだ分割の余地があります
  • 1つの表が1つのテーマだけを扱っているか:受注情報と商品情報が混在していないかを確認します
  • 導出可能なデータが残っていないか:計算で求められる項目が含まれていないかを確認します

正規化によって表の数は増えますが、それぞれの表がシンプルになり、データの管理がしやすくなります。必要なときには表同士を結合して、元のデータを復元することが可能です。

試験で出るポイント

正規化に関する問題は、ほぼ毎年出題されています。「重複と不整合をなくすために表を分割する作業=正規化」という定義と、具体的な表の分割例(受注表と商品表への分割など)の両方を押さえておきましょう。


過去問に挑戦

Q. 売上伝票のデータを関係データベースの表で管理することを考える。売上伝票の表を設計するときに,表を構成するフィールドの関連性を分析し,データの重複及び不整合が発生しないように,複数の表に分ける作業はどれか。

  • ア 結合
  • イ 射影
  • ウ 正規化
  • エ 排他制御
解答(令和元年)

正解: ウ

Q. 次に示す項目を使って関係データベースで管理する “社員” 表を設計する。他の項目から導出できる,冗長な項目はどれか。

社員

社員番号社員名生年月日現在の満年齢住所趣味
  • ア 生年月日
  • イ 現在の満年齢
  • ウ 住所
  • エ 趣味
解答(令和2年)

正解: イ

Q. 一つの表で管理されていた受注データを,受注に関する情報と商品に関する情報に分割して,正規化を行った上で関係データベースの表で管理する。正規化を行った結果の表の組合せとして,最も適切なものはどれか。ここで,同一商品で単価が異なるときは商品番号も異なるものとする。また,発注者名には同姓同名はいないものとする。

受注データ

受注番号発注者名商品番号商品名個数単価
T0001試験花子M0001商品153,000
T0002情報太郎M0002商品234,000
T0003高度秋子M0001商品123,000
  • ア | 受注番号 | 発注者名 |

| 商品番号 | 商品名 | 個数 | 単価 |

  • イ | 受注番号 | 発注者名 | 商品番号 |

| 商品番号 | 商品名 | 個数 | 単価 |

  • ウ | 受注番号 | 発注者名 | 商品番号 | 個数 | 単価 |

| 商品番号 | 商品名 |

  • エ | 受注番号 | 発注者名 | 商品番号 | 個数 |

| 商品番号 | 商品名 | 単価 |

解答(令和6年)

正解: エ

もっと過去問を解きたい方へ

フライトパスアプリなら、詳しい解説や分野別の過去問演習、SRS(間隔反復)学習ができます。

アプリで効率的に学習しよう