Posted at

DB 備忘録 (正規化について)


はじめに

 DBの基本がわかっていなかったので備忘録として書き残しています。

 完全初心者向けです。

 何か間違いがあったら、教えてください。


正規化

 正規化とは、「DBの各テーブル(エンティティ)について、システムでの利用がスムーズに行えるように整理する作業」です。

 DBの基礎がわからず行き当たりばっかりでテーブルを作ってしまうと、余計なカラムを作ってしまうことが多いと思います。その結果、無駄なデータ領域を取ったり、エラーの原因になったりします。そのために決まったルールでテーブルを整理しようというものです。(できる人は最初から正規化が完了したテーブルの構成になっているのかもしれませんが、、)

 正規化には何段階かレベルがあり、一般的には第1~5正規形で構成されます。ですが通常業務で使われるのは第1~3正規形まで考えて止めることが多い(らしい)ので、そこまでマスター出来れば大丈夫(らしい)です。

 以下でそれぞれの正規形について紹介していきます。


第1正規形

 第1正規形とは、「一つのセルの中には一つの値しか含まないテーブル」です。そんなこと当たり前だろと思われるかもしれません。以下に第1正規形でないテーブルの例を挙げておきます。

User_ID
名前
経験したスポーツ

21
たかし
野球、サッカー

43
けんと

46
さちこ
テニス

 上のテーブルでは一つのセルに二つ値が含まれてしまっています。実生活でこのようなテーブルを目にすることが多いとは思いますが、これは第1正規形とは呼べません。けんと君のセルがNULLになっていますが主キーでなければこれはOKです。

 上のテーブルを第1正規化すると以下のような形になります。ご確認ください。

User_ID
名前
経験したスポーツ1
経験したスポーツ2

21
たかし
野球
サッカー

43
けんと

46
さちこ
テニス


第2正規形 (部分関数従属の削除)

 第2正規形とは、「テーブル内で部分関数従属を解消し、完全関数従属のみで表したテーブル」です。例として第1正規形の以下のテーブルを第2正規化することを考えます。

チームコード
チーム名
本拠地
メンバーID
名前
ポジションコード
ポジション

001
浦安ブルーズ
浦安
6
たかし
00A
FW

002
ガンバ大分
大分
15
けんと
00B
MF

001
浦安ブルーズ
浦安
7
だいすけ
00C
GK

002
ガンバ大分
大分
7
はやと
00A
FW

 4人はそれぞれ浦安ブルーズか、ガンバ大分というサッカーチームに所属しています。

 第2正規化をするために、まずは候補キーは何かを考えます。候補キーとは、「行を一意に識別するために必要最低限の組合せ」です。つまり主キーを見つければそれが候補キーになるわけです。主キーが一列だけで表せれば良いのですが、主キーが見つからず、複数列を組み合わさなければ主キーが作れないことがあります。今回のテーブルはそのケースです。テーブルを見てみると、まずチームコードが決まるとチーム名、本拠地が決まることがわかります。同時にメンバーIDが決まると名前が決まることもわかります。このチームコードとメンバーIDを組み合わせることで主キーが作れるので、この二つが今回の候補キーとなります。ポジションコードも一見使えそうですが、他の列とどう組み合わせても主キーが作れないためNGです。

 今度は部分関数従属について考えます。部分関数従属とは、「候補キーの一部に対して他の項目が決まる」ということです。今回のテーブルではチームコードとチーム名、本拠地に従属性があることがわかります。

 第二正規形とは、「テーブル内で部分関数従属を解消し、完全関数従属のみで表したテーブル」なので、テーブルを分割することで、この従属性を削除することを試みます。

チームコード
メンバーID
名前
ポジションコード
ポジション

001
6
たかし
00A
FW

002
15
けんと
00B
MF

001
7
だいすけ
00C
GK

002
7
はやと
00A
FW

チームコード
チーム名
本拠地

001
浦安ブルーズ
浦安

002
ガンバ大分
大分

 試みたものが上のテーブルです。一つ目のテーブルでは部分関数従属の関係にあったチーム名、本拠地を二つ目のテーブルに追放することで完全関数従属のみで表したテーブルになっています。二つ目のテーブルが完全関数従属のみで表したテーブルだということは言わずもがなです。

 このように第2正規形で表すとシンプルにテーブルを書くことができます。


第3正規形 (推移的関数従属)

 第3正規形とは、「テーブル内で推移的関数従属を解消し、完全関数従属のみで表したテーブル」です。例として第2正規形で例として用いた以下のテーブルを第3正規化することを考えます。

チームコード
メンバーID
名前
ポジションコード
ポジション

001
6
たかし
00A
FW

002
15
けんと
00B
MF

001
7
だいすけ
00C
GK

002
7
はやと
00A
FW

チームコード
チーム名
本拠地

001
浦安ブルーズ
浦安

002
ガンバ大分
大分

 一つ目のテーブルに注目してみるとポジションコードとポジションに従属性がある事がわかります。一方でメンバーIDとポジションコードにも従属性が存在します。このことから、メンバーIDとポジションに関してもポジションコードを介して従属している事がわかります。このような2段階の関数従属を推移的関数従属と呼びます。この従属性を削除する事が第3正規化です。実際に第3正規化した第3正規形を下に示します。

チームコード
メンバーID
名前
ポジションコード

001
6
たかし
00A

002
15
けんと
00B

001
7
だいすけ
00C

002
7
はやと
00A

チームコード
チーム名
本拠地

001
浦安ブルーズ
浦安

002
ガンバ大分
大分

ポジションコード
ポジション

00A
FW

00B
MF

00C
GK


おわりに

 今回は第3正規化までを書きました。さらに正規化を進める場合(ボイス-コッド正規形、第4正規形、第5正規形)に関してはまた時間があるときに書き足したいと思います。