アプレンティス11期生の吉川です。
本記事では正規化についてまとめます。
復習および、現時点での自分の認識を再確認する目的もあります。
正規化とは
正規化とはデータが重複したり、データ更新の際に矛盾が生じないようにテーブルを分けることです。
データベース設計において重要になってきます。
下のテーブルを見てください。
| 学籍番号 | 学生名 | メールアドレス | 教員番号 | 教員名 |
|---|---|---|---|---|
| 1 | 太郎 | hoge1@hoge | 1 | 高橋権三郎 |
| 2 | 浩太 | hoge2@hoge | 2 | 鈴木愛 |
| 2 | 花子 | hoge3@hoge | 2 | 鈴木愛 |
学生とその担任みたいなイメージで結構です。
このテーブルにおいて、データの重複は、教員カラムの鈴木愛ですね。
たとえば「鈴木愛」先生が結婚して名字が変わったとしましょう。その場合データの重複があると手間がかかりますよね。
また、「太郎」君が転校したのでデータから削除したとします。そうするとテーブルからは「高橋権三郎」先生の存在まで消えてしまいます。可哀想!!
第一正規形
第一正規形とは属性(正規化の文脈ではカラムのことを属性と言ったりします)に繰り返しが無い状態にすることです。
データに繰り返しがある状態は非正規形と言います。
非正規形↓
| 学生番号 | 学生名 | メールアドレス | 教員ID | 教員名 | 試験ID | 試験名 | 得点 | 試験ID | 試験名 | 得点 |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 山田太郎 | hoge1@hoge | 1 | 伊藤一郎 | 1 | 漢検1級 | 80 | 3 | TOEIC | 942 |
| 2 | 鈴木愛子 | hoge2@hoge | 2 | 田中花子 | 2 | 英検1級 | 70 |
試験ID、試験名、得点がそれぞれ二回ずつ出てきますね。これは繰り返しがある状態なので、非正規形です。
ではこれを第一正規形にしてみましょう。
第一正規形↓
| 学生番号 | 学生名 | メールアドレス | 教員ID | 教員名 | 試験ID | 試験名 | 得点 |
|---|---|---|---|---|---|---|---|
| 1 | 山田太郎 | hoge1@hoge | 1 | 伊藤一郎 | 1 | 漢検1級 | 80 |
| 1 | 山田太郎 | hoge1@hoge | 1 | 伊藤一郎 | 3 | TOEIC | 942 |
| 2 | 鈴木愛子 | hoge2@hoge | 2 | 田中花子 | 2 | 英検1級 | 70 |
繰り返しはレコードを追加することで回避します。これで第一正規化完了!
第二正規形
第ニ正規形とは、部分関数従属が無い状態にすることです。部分関数従属を理解するために、まず主キー(プライマリーキー)と関数従属について理解しましょう。
主キーとはレコードを一意に識別するためのカラムのことです。
先ほどの例でいえば学生番号なんかが主キーとして良さそうですが、それだけでは一意に識別できませんよね。
ここで朗報!なんと主キーは1個でなくてもいいのです!
なので、学生番号と試験IDで主キーとしましょう(こういうのを複合主キーと言います)
関数従属とはxが決まればyも決まるという関係のことです。こういう関係を「yはxに関数従属する」と言います。また「→」を使ってx→yと書くこともあります。
学生番号が決まれば学生名も決まる、教員番号が決まれば教員名も決まる、こういうのが関数従属です。
また、学生番号と試験IDが分かれば得点もわかる。これも関数従属です。
正規化では関数従属の種類が重要になってきます。3種類ある関数従属についてもきっちり理解しましょう。
完全関数従属
主キーとなっている属性の値がすべてわかったときに、他の属性の値も一意に決まることです。
簡潔に言うと、属性が主キーに関数従属するということです。
さっきの例でいうと、{学生番号、試験ID}→{得点}のことです
部分関数従属
属性が主キーの一部に関数従属することです。要は主キー全部じゃなくて、一部だけでもわかれば、他の属性の値が分かるということです。
さっきの例でいうと、{学生番号}→{学生名}や{試験ID}→{試験名}のことです。
推移的関数従属
属性x、y、zについて{x}→{y}、{y}→{z}という関係があるとき、zはxに推移的関数従属すると言います。
さっきの例でいうと、{学生番号}→{教員ID}→{教員名}のことです。
属性が主キー以外の属性に関数従属すると考えてもよさそうです。{教員ID}→{教員名}という関数従属は、主キーが全く絡んできませんからね。
思い切って3種類一気に解説しましたが、第二正規化で行うのは部分関数従属の解消でしたね。
具体的にどう解消するかというと、テーブルを分割するんです。
(以下では、属性名だけ記述し、具体的なデータは省略します)
| 学生番号 | 学生名 | メールアドレス | 教員ID | 教員名 |
|---|
| 学生番号 | 試験ID | 得点 |
|---|
| 試験ID | 試験名 |
|---|
下線で引いたところが各テーブルの主キーです。こういう属性名だけ抽出する表記法も便利なので使えるようになりましょう。
さて、上のようにテーブルを分割すると確かに部分関数従属がなくなりましたね。
ここで、第二正規化の目的について触れておきます。
例えば、試験名が「漢検1級」から「漢検1級ver.2」に変わったとしましょう。
第二正規化をしていなかったとすると、漢検1級の受験者の数だけ修正を入れなければなりません。
しかし、第二正規化をしたことによって、「試験ID」と「試験名」からなるテーブルの「試験ID」が1のレコードの「試験名」を「漢検1級ver.2」に変えるだけで済むのです。
こういったデータ更新処理の時に楽なんですね。
第三正規形
第三正規形とは推移的関数従属が無い状態にすることです。
以下が第三正規形です。
| 学生番号 | 学生名 | メールアドレス | 教員ID |
|---|
| 教員ID | 教員名 |
|---|
| 学生番号 | 試験ID | 得点 |
|---|
| 試験ID | 試験名 |
|---|
第二正規形はこっち↓
| 学生番号 | 学生名 | メールアドレス | 教員ID | 教員名 |
|---|
| 学生番号 | 試験ID | 得点 |
|---|
| 試験ID | 試験名 |
|---|
見比べると、第二正規形で{教員ID}→{教員名}の推移的関数従属が存在したのを、テーブルを分割することによって解消していますね。
第三正規形の目的についても触れておきましょう。
例えば、まだ担任を務めていない新任教師のデータを加えたいとしましょう。このとき第ニ正規形のままだと学生のデータと教員のデータが紐づく形でデータを追加しなければならないので、まだ担任を務めていない新任教師のデータを加えるには不都合です。
第三正規形のように、主キーが絡まないような関数従属をテーブルを分割することで切り出してあげると、このようなケースにも対応できるってことです。
まとめ
本当は正規形には第五正規形まで存在するのですが、第三正規形までで十分実用的とされています。
第三正規形までは理解して、かつ自らの手でもできるようになりたいですね。
参考文献
著者:高橋 京介「【令和6年度】 いちばんやさしい 基本情報技術者 絶対合格の教科書+出る順問題集」