データの断捨離術:データベース正規化ガイド
7分43秒 | DB設計
基本情報技術者試験の頻出テーマを解説した動画コンテンツです。
トランスクリプト(字幕テキスト)
どうも。突然ですが、みなさんの部屋、散らかってませんか? どこに何があるかわからないクローゼットとか、ちょっと不便ですよね。 実はデータベースも全く同じなんです。というわけで今日は、このデータのゴチャゴチャをスッキリさせる エレガントなお片付け術、「正規化」について見ていきましょう。 いやいや、でもちょっと待ってと。全部ひとつの箱に放り込んじゃえば、探すの逆に楽じゃない?って思いますよね。 データベースだって同じで、すべての情報をドーンとひとつの巨大なテーブルにまとめたほうが、一見するとわかりやすそうに見えます。 でも本当にそうでしょうか?例えば、これ。まさにデータ収集家の部屋状態の、カレー屋さんの注文管理表です。 仕入れ先とか商品とか、注文の記録が全部ごちゃ混ぜ。パッと見は便利そうなんですけど、 よく見るとその下にはカオスが広がってます。ほら、同じ仕入れ先の名前とか担当者名が、 注文が入るたびに何度も何度も繰り返し記録されてますよね。このごちゃまぜ状態が、 実は3つのすごく厄介な問題を引き起こすんです。それが、更新、挿入、削除のアノマリー、まあデータの不整合ってやつですね。 例えば、担当者が変わっただけなのに、過去の注文を全部手作業で修正するなんて大変だし、絶対ミスしますよね。 新しい取引先を追加したいだけなのに、注文がないと登録できないとか。で、最悪なのが、 たったひとつの注文を消したはずが、大事な顧客情報まで一緒に消えちゃった、なんてことです。 これはもう一刻も早くなんとかしないとまずいですよね。そこでいよいよ登場するのが、「データの断捨離」です。 これは単なる面倒な作業じゃなくて、データを美しく整理するためのすごく強力な手法なんです。その名も、「正規化」。 正規化って何かと言うと、すごく簡単に言えば、データのダブりをなくして矛盾が起きないように テーブルを上手に分割していく作業のことです。目的は、データの整合性をしっかり保って管理を楽にすること。 まさにデータベース界のお片付け術ってわけですね。それでは早速、断捨離の旅を始めましょう。 最初のステップは、第一正規形。これはもう基本中の基本で、 すべてのアイテムにそれぞれ専用の棚を確保してあげようっていうルールです。 こちらが整理前の状態です。カレーの材料を注文したんでしょうけど、 ひとつのマスの中に玉ねぎ、人参、じゃがいもみたいに、複数の商品がカンマ区切りで入っちゃってます。 これ、データベースの世界ではルール違反なんです。ひとつのマスにはひとつの値だけ。 この繰り返しのグループがまず問題なんですね。そしてこれが整理後です。 ごちゃっと入っていた商品を、それぞれ独立した行に分けてあげました。 これでひとつのセルにはひとつの値だけ、という大原則が守られましたね。これが第一正規形。 まずはデータベースにデータをちゃんと格納できる、最低限の形になったということです。 さあ、お片付けは次のレベルに進みますよ。ここからが本格的な分割作業です。 イメージとしては、カテゴリーごとに専用の収納ボックスを作っていく感じですね。 ここで解決すべき問題が、「部分関数従属」です。なんだか難しそうに聞こえますけど、 要するに、情報を特定する鍵全体じゃなくて、その一部だけで決まっちゃう情報が混ざってるよっていう状態のことなんです。 この表、面白さがわかりますか?この表の主キー、つまりそれぞれの行を特定するための鍵は、 仕入れ先IDと商品ID boundary 2つでワンセットです。でも、よく見てください。 仕入れ先名とか所在地って、商品IDが何か等全然関係ないですよね。仕入れ先IDさえわかれば、もう特定できちゃう。 これ、無駄じゃないですか?商品の情報とは直接関係ない仕入れ先の情報が、注文のたびに何度も何度も繰り返されてる。 見つけちゃいました、プロの無駄。この部分関数従属を解消するために、テーブルを分割します。 仕入れ先に関する情報は仕入れ先テーブルとして、購入の記録は購入履歴テーブルとして、スパッと切り離します。 これで仕入れ先の情報がダブることなく一箇所で管理できる。あ、スッキリしましたね。 さあ、いよいよ断捨離も最終ステップです。すべてのデータを本来あるべき最終的な場所に収めていきましょう。 ここで断ち切るべきなのは、「推移的関数従属」っていう依存の連鎖です。 これは鍵以外の項目から、さらに別の項目が決まってしまうっていう、まあ数珠繋ぎみたいな関係性のことですね。 さっき作った仕入れ先テーブル、もう一回見てみましょうか。主キーは仕入れ先IDですよね。 で、ここには担当者名とその連絡先も入ってます。でも、よく考えてみてください。 仕入れ先IDがわかれば担当者名が決まる。そしてその担当者名がわかれば連絡先も決まる。 AからBに、BからCに連鎖です。これもまた非効率。だって担当者の連絡先は担当者本人に紐づく情報であって、 仕入れ先そのものの情報じゃないですからね。はい、見つけました。 ですからこれもバッサリいきましょう。担当者の情報を担当者テーブルとして独立させます。 これで主キー以外の属性への依存関係がなくなりました。これが第三正規形です。 さあ、私たちのこれまでの努力の結果を見てみましょう。あの混沌としていたデータがどれだけスッキリと明瞭になったか。 どうですかこれ。正規化を終えたデータベースの最終形態です。 それぞれの情報が、それぞれに最適な小さなテーブルにきちんと収まって、お互いの関係が線で結ばれている。 データの重複は一切なく、すべての情報があるべき場所にいる。うーん、美しい。 この整理整頓後の達成感、たまらないですね。と言いたいところなんですが、 ここでひとつ、すごく重要な現実問題について考えてみましょう。この完璧な整理整頓、 いつでもどこでも、本当にベストな選択肢なんでしょうか?実は、ここにはトレードオフがあるんです。 正規化を進めれば進めるほど、データはクリーンになって整合性も保たれる。これは大きなメリットです。 でもその反面、パフォーマンス、つまり処理速度が落ちることがあるんです。 なぜかっていうと、例えば「あの注文の玉ねぎを卸してくれた業者の担当者の連絡先教えて」って情報を得るために、 バラバラにした注文テーブル、仕入れ先テーブル、担当者テーブルを全部ジョイン、つまり繋ぎ合わせて確認しなきゃいけない。 このジョイン作業が、コンピューターにとってはちょっとした負担になることがあるんですね。 「第三正規化まですればいいというのは嘘です」。このちょっと挑発的な言葉、実はすごく本質を突いてるんです。 正規化はここまでやればOKっていう絶対的なルールじゃなくて、あくまで道具なんですね。 第三正規形までで十分なこともあれば、もっと先に進む必要がある場合もある。 それどころか、パフォーマンスを上げるためにあえて正規化を少し崩す「非正規化」っていう選択肢を取ることすらあるんです。 一番大事なのは、データの不整合を防ぐっていう大前提を守りつつ、システムの目的や性能に合わせて、 どこまで冗長性を許容するかを考えることなんです。みなさんが今扱っているデータ、 その目的にとって本当に最適な整理レベルにあるでしょうか?ぜひこの機会に一度考えてみてください。今回の解説は以上です。
このコンテンツは Web society で視聴・学習できます。