テクノロジ系データベース出題頻度 ★★

正規化

データの重複をなくして矛盾を防ぐ「正規化」を、お店の注文伝票を表に分けていく例と図で解説。第1正規形・第2正規形・第3正規形で何を取り除くのかがわかり、表をどう分割すべきかを問う問題が解けるようになります。

この単元の用語:正規化 / 非正規形 / 第1正規形 / 第2正規形 / 第3正規形 / 関数従属 / 部分関数従属 / 推移的関数従属 / 更新時異状

データベースの「正規化」って、なんだか難しそうな名前ですね。

やっていることは「同じことを何度も書かないように、表を分ける」だけなんだ。お店の注文伝票を例に、一歩ずつ分けてみよう。

なぜ表を分けるの?:更新時の矛盾

ある文房具店では、注文をこんな1つの表で管理していました。

受注番号受注日顧客番号顧客名商品番号商品名数量
1014/1C1山田商店P1ボールペン10
1014/1C1山田商店P2ノート5
1024/3C2鈴木書房P1ボールペン20
1034/5C1山田商店P3消しゴム8

「山田商店」が3回、「ボールペン」が2回出てきます。これが困りごとの原因です。

山田商店が「ヤマダ文具」に社名変更 受注番号 顧客番号 顧客名 101 C1 ヤマダ文具 101 C1 ヤマダ文具 103 C1 山田商店 ✔ 直した ✔ 直した ✕ 直し忘れ! 同じC1なのに名前が2種類 → どちらが正しい?
同じデータが何か所にもあると、1か所の直し忘れでデータが矛盾する

このように、重複したデータがあるせいで起きる不都合を 更新時異状(更新時の異常)といいます。

  • 修正の異状:1か所直し忘れると矛盾する(上の図)
  • 追加の異状:まだ注文のない新商品を登録したくても、受注番号がないので行を作れない
  • 削除の異状:注文103を削除すると、「消しゴム」という商品の情報まで消えてしまう

そこで、1つの事実を1か所にだけ記録する ように表を分けていきます。これが 正規化 です。

準備:「決まる」関係(関数従属)

正規化では 「Aが決まれば、Bが1つに決まる」 という関係に注目します。これを 関数従属 といい、A → B と書きます。

  • 顧客番号 → 顧客名(C1なら必ず山田商店)
  • 商品番号 → 商品名(P1なら必ずボールペン)
  • 受注番号 → 受注日、顧客番号
  • 受注番号 + 商品番号 → 数量

正規化の3ステップ

非正規形 繰返しがある 第1正規形 繰返し項目を なくす 第2正規形 主キーの一部で 決まる項目を 別の表へ 第3正規形 主キー以外の項目で 決まる項目を 別の表へ ゴール
階段を1段ずつ上るように、表を分けていく

ステップ1:第1正規形(繰返しをなくす)

紙の伝票では、1枚の中に商品が何行も並びます。このように 1件の中に同じ種類の項目がくり返し並んでいる 状態を 非正規形 といいます。1行1件の形に直し、各セルに値が1つだけ入るようにしたものが 第1正規形 です。冒頭の表がちょうど第1正規形で、主キーは 受注番号+商品番号 の組です。

ステップ2:第2正規形(主キーの一部で決まるものを分ける)

主キーは「受注番号+商品番号」なのに、受注日は 受注番号だけ で、商品名は 商品番号だけ で決まります。このように 主キーの一部だけで決まる 関係を 部分関数従属 といい、これを別の表に分けると 第2正規形 になります。

ステップ3:第3正規形(主キー以外で決まるものを分ける)

受注の表では、顧客名は主キーの受注番号ではなく 顧客番号 で決まります(受注番号 → 顧客番号 → 顧客名)。このように 主キー以外の項目を経由して決まる 関係を 推移的関数従属 といい、これを別の表に分けると 第3正規形 になります。

受注 受注番号, 受注日, 顧客番号 101, 4/1, C1 / 102, 4/3, C2 … 顧客 顧客番号, 顧客名 C1, 山田商店 / C2, 鈴木書房 受注明細 受注番号, 商品番号, 数量 101, P1, 10 / 101, P2, 5 … 商品 商品番号, 商品名 P1, ボールペン / P2, ノート … 太字が主キー。山田商店は顧客表の1か所だけに記録される
第3正規形の完成形。社名変更は顧客表の1行を直すだけで済む

表が4つに増えちゃいました。かえって不便じゃないですか?

いい視点だね。確かに「注文ごとの顧客名」を見たいときは、表を結合してつなぎ直す手間がかかる。でも、データの矛盾を防げるメリットのほうが大きいから、まずは正規化するのが基本なんだ。

3つの正規形の比較

段階取り除くものひとことで
第1正規形繰返し項目1つのセルに1つの値
第2正規形部分関数従属(主キーの一部で決まる項目)複合主キーの「片方」で決まるものを分ける
第3正規形推移的関数従属(主キー以外の項目で決まる項目)「キーでない列」で決まるものを分ける

1・2・3 = 繰返し・部分・推移。「くり・ぶぶ・すい」と唱えて覚えよう。

正規化は 検索を速くするためのものではありません。目的は 重複の排除と、更新時の矛盾の防止 です。「正規化すると表の数が減る」「結合が不要になる」という選択肢は誤りです。

試験に出るポイント

  • 正規化の目的は、データの重複をなくし、更新時異状(矛盾)を防ぐ こと
  • 第1正規形:繰返し項目をなくす
  • 第2正規形:主キーの一部だけで決まる項目(部分関数従属)を別の表へ
  • 第3正規形:主キー以外の項目で決まる項目(推移的関数従属)を別の表へ
  • 分けた表は、共通の列(外部キー)で 結合 すれば元の情報を復元できる

確認クイズ

選択肢をタップすると、すぐに正解と解説が表示されます。

Q1関係データベースの表を正規化する主な目的として、適切なものはどれか。

Q2表「社員(社員番号, 氏名, 部署コード, 部署名)」では、部署名が部署コードによって決まる。同じ部署名が何度も現れないようにする分割として、適切なものはどれか。各表の先頭の列を主キーとする。

Q3非正規形の表から、繰返し項目(1件の中に同じ種類の項目が複数並ぶ部分)を取り除いた表を何というか。

Q4表「受注明細(受注番号, 商品番号, 受注日, 顧客番号, 顧客名, 商品名, 数量)」の主キーは受注番号と商品番号の組である。受注日と顧客番号は受注番号で、顧客名は顧客番号で、商品名は商品番号で決まり、数量は受注番号と商品番号の組で決まる。第3正規形まで正規化すると、表はいくつになるか。