いろいろ

元データベースエンジニアの独り言:逆正規化は腕の見せ所

スポンサーリンク

TLを眺めてて、データベースの正規化の話題を目にして

そういえば、正規化って奥が深いんだよ、というのを語りたくなったので

独り言です。

DB正規化の順序

ちょっと特殊な例を出します。

例えば、誰が、いつ、どのタイミング(朝食、昼食、夕食)で、何のラーメンを食べたのかを
記録するシステムがあるとします。

第1正規形:繰り返しを取り除く

この場合、R009:○○さんの記録が複数あります。

○○さん、繰り返しの記録があります。
この状態は、非正規形です。

この繰り返しをなくすことが、第一正規形になります。
主キーに対して1レコードになります。
この場合の主キーは、「ラ族コード」「日付」「タイミング」になります。
この3つの項目で、1つのデータを特定できます。
※今回は1回の食事で複数種類のラーメンを食べるケースは想定していません。
 たまにTLで見かけますが。。。

これで繰り返しが無くなって、第一正規形になりました。

第2正規形:部分関数従属を排除する

部分関数従属とは、主キーの一部分の項目に関連することを指します。

このケースですと、主キーの1つ「ラ族コード」に「名前」が関連しています。

例えば、R009:○○さんの名前が変わって□□さんになったとします。
この場合、主キーで更新すると1件のみの更新となり、○○さんに関連するデータ全てが更新されません。

データの整合性を保つ、という意味で、この情報を別テーブルで管理するのが第2正規形になります。

これで、○○さんの名前が変わったときは
ラ族テーブルのR009のデータを更新するだけで済みます。

これが第2正規形です。

第3正規形:推移関数従属を排除する

推移関数従属とは、主キーでは無い項目に関連することを指します。
今回の例では、主キー項目ではない「お店コード」と、それに関連する「お店の名前」が
推移関数従属となります。

これも、データの整合性を保つ、という意味で、別テーブルにします。

これで第3正規形までいきました。

第4正規形、第5正規形は実際に出会ったことないし知らなくても生きていける

正規化は、詳しくは第4正規形、第5正規形もあります。

私も勉強して、存在は知っていますが、詳細は忘れました。。。

ただ、情報処理の試験でも出てきませんし(私の知る限り)
実際の業務でお目にかかったことはありません。

なんなら、第3正規形まで知ってて
アプリ設計者のテーブルレイアウト案に対して
正規化の観点で修正の指摘をすることができます。
それで十分だと思います。(個人の感想です。。。)

正規化をし過ぎるとレスポンスが悪くなる

このように、テーブルの正規化をすることで
データの整合性が保たれるわけですが
あまりに正規化し過ぎると、テーブルの結合が多くなり
かえってレスポンスが悪くなります。

正規化の部分は、データベース設計では論理設計になりますが
レスポンスを考慮した設計は、物理設計の分野になります。

ここが、データベースエンジニアの腕の見せ所です。

レスポンス対策では逆正規化を行うことがある

今までさんざん正規化しましょうと言ってきましたが
じゃあレスポンスを犠牲にしてまで正規化を貫きとおすのかというと
そういうわけではなく
必要に応じて正規化の逆、逆正規化を行います。

往々にして行われる逆正規化は
第一正規形で排除した繰り返し項目をあえて戻す、ということです。

例えば、先ほどの例でいうと

このテーブルで、例えばある人が1年365日毎食ラーメンを食べたとします。

その場合、データは365日×3食なので1,095件になります。

1,095件、まあまあの件数です。

これで、例えばレスポンスが悪いので、逆正規化をしよう!という話になります。

まず考えることは「タイミングって、朝、昼、夜の3つ限定じゃね?」という点です。
その観点で逆正規化をすると、このようになります。

このようなレイアウトにすることで、1年で最大365件に抑えられます。

1年で最大365件。。。
まだ件数多い。。。

という場合は、「1年ってうるう年でも366日しかなくね?」と考えます。
そうなると、このようなレイアウトになります。

これで、1年でも最大1行、80年生きたとしても最大80件になります。
SQLもすぐレスポンス返してくれます。

このように、あらかじめ枠が決まっているのであれば
あえて繰り返し項目を存在させてレコード件数を減らす、ということをして
レスポンスを向上させることをするのです。

これは1年365日で逆正規化してみましたが
例えば、枠が決まってない場合でも
例えば100件単位で繰り返し項目を持たせるとか
そういうことをして、レコード件数を減らすことをします。

非正規化のデメリット:プログラムの処理が煩雑になる

ただ、非正規化を行うことのデメリットがあります。

それは、プログラムの処理が煩雑になる、ということです。

上記の例であれば、○月○日はどの項目に該当するのかを
プログラムが判断することになります。
なので、プログラムが煩雑になります。
お店の名前も、コードから逆引きする必要があるので
お店マスタをメモリに常駐させて、都度メモリから名前を持ってくるとか
そういう対応が必要になります。

ここは、データベースエンジニアとプログラマーとの調整になります。
まあ、レスポンスが悪いとなると、どうしても非正規化をする必要があるので
プログラマーにお願いすることになりますが
それでもデータベースのレスポンスは向上するので
データベースエンジニアは心の中でガッツポーズしてます。(個人の感想です)

たぶん、早いレスポンスを求められる会計系のシステムでよく見かけます。(個人の感想です)

ということで
たまに

「なんでこのテーブル繰り返し項目があるんだよ!設計者正規化知ってる?」

と思う機会があるかと思いますが

それは、データベースエンジニアが苦労して編み出したレイアウトの可能性があるので

生暖かい目で見ていただけますと幸いです。

スポンサーリンク

-いろいろ