データベース正規化

f:id:utouto97:20210725220811j:plain

データベース正規化

データベース正規化は、データの重複を防ぎ、整合性を保ちやすいように、データベースを設計することです。
データベースの正規系は、第1正規系、第2正規系、第3正規系、・・・とあります。
また、ボイスコッド(BC)正規系というのもあります。

「なんで正規化するの?」

データベースが保持するデータに重複があったり、矛盾が発生すると問題が発生してしまいます。
そのような問題が発生しにくいような設計をすることが、データベースの正規化となります。
そして、データベースの整合性を保つことが、正規化の目的となります。

正規化されていないデータベースだと、ある一つの値を変更した際に、変更忘れが発生したりします。
例えば、次のようなデータベースがあるとします。
このデータベースでは、部署ごとに内線の番号が決まっているとします。

社員番号 名前 部署 内線 担当
1 佐藤健太 人事部 AAAA 新卒,中途
2 坂本 隆 営業部 BBBB 外回り
3 本多 健一 人事部 AAAA 新卒
4 森川 淳 営業部 BBBB 外回り
5 森田 卓哉 営業部 BBBB 外回り

ここで、営業部の内線番号がCCCCに変更されたとします。
すると、変更箇所が3か所もあり、変更忘れが発生する可能性があります。
データ数がもっと増えると、変更忘れの可能性が高まるだけでなく、変更にかかる計算コストも非常に大きくなってしまうといった問題も発生してしまいます。

第k正規系

データベースの正規化された形には、第〇正規系と呼ばれる形がいくつかあります。
第1正規系からはじまり、第2正規系、第3正規系と続きます。

今回は、第1正規系、第2正規系、第3正規系だけをまとめていきます。
このほかにも、第4正規系や第5正規系、ボイスコッド(BC)正規系というのもあります。

「結局、正規化はなにすればいいの?」

第1正規系では、「1レコードの1カラムには1つの値」といったルールを適用します。
プログラミングでイメージするならば、各カラムの値に、配列を利用してはならない、ということになります。
また、カンマ区切りやスペース区切りで複数の値を一つの値にまとめるのもダメです。

上で使った社員のデータベースを参考に、第1正規系になるように変更してみます。
このテーブルは、担当にカンマ区切りで複数の値が含まれています。
これを一つの値しか持たないようにします。

社員番号 名前 部署 内線 担当
1 佐藤健太 人事部 AAAA 新卒
1 佐藤健太 人事部 AAAA 中途
2 坂本 隆 営業部 BBBB 外回り
3 本多 健一 人事部 AAAA 新卒
4 森川 淳 営業部 BBBB 外回り
5 森田 卓哉 営業部 BBBB 外回り

第2正規系では、「主キーにおいて、部分関数従属が存在しない」といったルールを適用します。
また、第3正規系では、「非キー→非キーにおいて、関数従属が存在しない」といったルールを適用します。
主キーや非キー、関数従属といった言葉の説明はここでは省きます。

第3正規系にするには、「主キーにおいて、部分関数従属が存在しない」と「非キー→非キーにおいて、関数従属が存在しない」のルールを適用すればよいです。
つまるところ、Aが決まればBが決まる場合、A→Bがわかるようなテーブルを新たにつくり、元のテーブルにはAだけ含めればよい、ということになります。

例えば、上の社員のテーブルの場合、社員番号が決まれば、「名前」「部署」「担当」が決まります。
また、部署が決まれば、「内線」は決まります。

ということで、これらのテーブルを分解します。

社員番号 名前 部署
1 佐藤健太 人事部
2 坂本 隆 営業部
3 本多 健一 人事部
4 森川 淳 営業部
5 森田 卓哉 営業部
部署 内線
人事部 AAAA
営業部 BBBB
社員番号 担当
1 新卒
1 中途
2 外回り
3 新卒
4 外回り
5 外回り

終わり