いつか、技術ブログを

新人SE(OJT中)が技術ブログを書きたがっているブログです

応用情報対策で正規化について説明してみる

正規化って難しいですよね…
難しいポイントは2つあると思っていて、

  • 第1正規形、第2正規形、第3正規形と段階を踏むため、その段階別に何をするのか覚えなければいけない

  • 部分関数従属とか、完全関数従属とか、用語が難しい(参考書によっては、「集合Aが〜なとき、真部分集合が〜」みたいな意味不明な説明が書いてある)

といったところでつまずきやすいと思います。
なので、正規化について説明して、自分なりに整理してみます。

正規化とは

正規化とは、データの重複をなくし、データの更新に適したテーブルとなるように整理することです。
一般的には、非正規形から、第1正規形、第2正規形、第3正規形まで順番に正規化します。

主キーと非キー

主キーとは、「この項目が決まれば他の項目も特定できるよ」という項目のことです。
f:id:ramenchahan:20180314101052p:plain
大学では、学籍番号が決まれば氏名や年齢(普通は生年月日ですけど)がわかる、っていう風になってますよね。この学籍番号が主キーです。

主キーは、複合キーであることもあります。複合キーとは、複数の項目の組み合わせで他の項目を特定できる項目のことです。 f:id:ramenchahan:20180314094643p:plain
この例では、「クラスと出席番号」から、氏名や担任がわかりますよね?
ですが、出席番号1番、というだけでは、山田くんなのか鈴木くんなのかわかりません。
なので、クラスと出席番号の複合キーが主キーである、ということになります。

主キーでないものは「非キー属性」とか「非キー」とかいいます。

関数従属とは

関数従属とは、「ある項目によって他の項目が決まること」です。
上の例では、学籍番号が決まれば、氏名や年齢が決まるので、「氏名は学籍番号に関数従属する」と言えます。

非正規形

非正規形は、繰り返しの項目があるような形です。
f:id:ramenchahan:20180314102154p:plain
1行ごとに並べ替えたりするだけでも大変そう、というか無理じゃない?って思うような表です。 f:id:ramenchahan:20180314103707p:plain
列の方に繰り返しがあるのも非正規形といいます。3つ以上商品買う時どうするの?列を増やすの?っていう表です。

今回は、この学生表の方を正規化していきます。
f:id:ramenchahan:20180314102154p:plain

第1正規形にする

非正規形から第1正規形にするには、繰り返し項目をなくします。
f:id:ramenchahan:20180314102206p:plain
この例では、クラス、担任番号、担任氏名を1行ずつに分割しました。
よく「繰り返し項目をなくす」とか「非キーに関数従属する非キーを排除する」とか書いてありますが、基本的には「分割する」という意味です。

第2正規形にする

第1正規形から第2正規形にするには、主キーの一部に関数従属する非キーをなくします。
f:id:ramenchahan:20180314102206p:plain
第1正規形の表を見てみると、主キー(クラス、出席番号)の一部である「クラス」に、非キーである「担任番号」と「担任氏名」が関数従属していることがわかります(「クラス」が決まれば「担任番号」と「担任氏名」が決まるという意味です)。
なので、「担任番号」と「担任氏名」をこの「学生表」から出してあげれば第2正規形とすることができます。
ということで、学生表の他に、以下のようにクラス担任表を作ります。
f:id:ramenchahan:20180314110151p:plain
なぜ「担任番号」と「担任氏名」を出す、と言ったのに「クラス」もクラス担任表に入れたかというと、そうしないと結局先生がどのクラスの担任なのか分からなくなってしまうからです(当たり前ですかね?私は最初疑問に思ったので 笑)。

ちなみに、「非キーが主キーの一部に関数従属する」ことを部分関数従属と言い、「非キーが主キーの一部に関数従属していないこと(主キーの一部ではなく全部が決まることによって初めて非キーが決まること)」を完全関数従属と言います。
「主キーの一部」という言い方をするのは、主キーが複合キーであることが前提だからです。
なので、はじめから主キーが1列なら、非正規形の繰り返し項目をなくせば自動的に第2正規形になります。

第3正規形にする

第2正規形から第3正規形にするには、非キーに関数従属する非キーをなくします。
まず、第2正規形の学生表を見てみると、非キー(出席番号、氏名)に関数従属するキーはないので、学生表は自動的に第3正規形となっていることがわかります。
f:id:ramenchahan:20180314110151p:plain
次に第2正規形のクラス担任表を見てみると、非キーである「担任番号」に非キーである「担任氏名」が関数従属しています(1クラスに担任は1人で、クラスが主キーという設定です)。なので、「担任氏名」をクラス担任表から出すことで、クラス担任表も第1正規形となります。
ということで、教師表を作り、以下のようにします。
f:id:ramenchahan:20180314111449p:plain

ちなみに、Aが決まるとBが決まり、Bが決まるとCが決まるとき、CはAに推移関数従属していると言います(言い換えると、CがBに関数従属し、BがAに関数従属するとき、CはAに推移関数従属するということです)。
f:id:ramenchahan:20180314115333p:plain
第2正規形のクラス担任表を見てもらうと、クラスが決まると担任番号が決まり、担任番号が決まると担任氏名が決まる、という状況なので、「担任氏名」は「クラス」に推移関数従属していると言えます。

まとめ

非正規形:繰り返し項目あるもの
第1正規形:繰り返し項目なくしたもの
第2正規形:主キーの一部に関数従属する非キーなくしたもの
第3正規形:他の非キーに関数従属する非キーなくしたもの

部分関数従属:主キーの一部に他のキーが関数従属していること
完全関数従属:主キーの一部に他のキーが関数従属していないこと(主キーの一部ではなく全部が決まることによって初めて他のキーが決まること)
推移関数従属:Aが決まるとBが決まり、Bが決まるとCが決まるとき、CはAに推移関数従属しているという

これらの用語を使って言い換えると↓
第2正規形:部分関数従属をなくしたもの または 主キーに他の項目が完全関数従属するようにしたもの
第3正規形:推移関数従属をなくしたもの

感想

書いてて思ったのですが、「第2正規形にする操作をしたはずなのにもう第3正規形になってた!」っていうことがよくあるのも、混乱する要因かもしれないですね…