データベーススペシャリストという資格がありますが、この資格取得のために勉強していると正規化について学ぶと思います。日常業務でDB論理設計を行った経験があれば、第3正規形まではすんなりと飲み込むことができる内容ではないでしょうか?
ですが、その後の
- ボイスコッド正規形
- 第4正規形
- 第5正規形
で理解に苦しんだり、そもそも何のためにやるのか疑問に思ったりする人が多いのではないでしょうか・・・。
今回はまず、「ボイスコッド正規形」について分かりやすい解説を書くことに挑戦してみようと思います。
実際に「分かりやすかった!」と思った方、スターを付けてくれると励みになります。第二弾として第4正規形にもチャレンジする気持ちになれそうです!
※ 第3正規形までは理解している前提でお話させていただきます。
シチュエーション
M君、O君、Y君、U君、F君の5人が東京にいます。時刻は午前8時。それぞれ、
- M君:すぐにインドに行きたい
- O君:すぐに福岡に行きたい
- Y君:すぐに沖縄に行きたい
- U君:夕方に福岡に行きたい(午前中は東京で用がある)
- F君:夕方に福岡に行きたい(午前中は東京で用がある)
いつ・どこに行きたいという目的を持っています。東京発の本日の飛行機は、
- XX101便:東京発ニューデリー行き 11時発
- XX201便:東京発福岡行き 10時発
- XX203便:東京発福岡行き 16時発
- XX401便:東京発那覇行き 10時発
というフライト予定となっています。
リレーション
上述のシチュエーションを表に整理してみると下記となります。
| 名前 | 目的地 | 利用便 |
|---|---|---|
| M君 | インド | XX101便 |
| O君 | 福岡 | XX201便 |
| Y君 | 沖縄 | XX401便 |
| U君 | 福岡 | XX203便 |
| F君 | 福岡 | XX203便 |
条件として、
- 誰がどこへいつ行きたいかによって、利用する便が一意に決定される
- 便によって行先は一意に決定される
ものとします。
従属性
ここでいきなり「従属性」と言われて「???」となるかもしれませんが、条件を踏まえて「何が決まると次に何が決まるか?」と考えていただければと思います。

- 名前と目的地が決まると、利用する便が確定する
- 利用する便が決まると、目的地が確定する
と考えてください。
1について同じ目的地の福岡であっても、O君はすぐに行きたいので利用便は「XX201便」になり、U君は夕方に行きたいので利用便は「XX203便」になります。F君も同様。これが、「名前と目的地が決まると、利用する便が確定する」ということです。
2については便が決まれば当然その目的地も決まりますよね。
思い出してほしい第3正規形の定義
第3正規形の定義は
1)関係Rは第2正規形である
2)関係Rのすべての非キー属性はRのいかなる候補キーにも推移的に関数従属しない
ということです。
2)について例を用いて説明すると
関係R(A,B,C)について、{A,B} が唯一の候補キーである({A,B}が決定するとCが確定する)とすると、非キー属性Cの決定によりAやBが確定しない
ということです。
ここで、名前・目的地・利用便の関係を改めて考えてみると、
- 名前と目的地が決定すると、利用する便が確定する ⇒{名前, 目的地}は候補キー
- 利用便が決定すると、目的地が確定する ⇒利用便の他に名前も決定すればデータを一意に特定できる ⇒{名前, 利用便}も候補キー
2つ目について、利用便が「XX203便」と決定するとU君とF君にデータが絞られるけど、更に名前まで確定すればデータを一意に特定できるということです。
とすると、この場合、先ほど述べた「非キー属性Cの決定によりAやBが確定しない」という条件を満たさないようにも見えますが、Cに相当する「利用便」も候補キーの一部(キー属性)であり非キー属性ではないことで、結果的に(名前, 目的地, 利用便)の関係は第3正規形を満たすことになります。
ボイスコッド正規形とは
ボイスコッド正規形の定義は
X→YをRの関数従属性とするとき以下のいずれかを満たす
・X→Yは自明な関数従属性である
・XはRのスーパーキーである
※ スーパーキー:データを一意に特定できる属性または属性の組
※ 自明な関数従属性とは、{A,B}が決定するとAが決定するようなケースを言う
となります。
ここで大切なことは第3正規形との違いです。
第3正規形では非キー属性→キー属性への従属性は認められないが、キー属性→キー属性は認められる
ボイスコッド正規形ではキー属性→キー属性も認めない(=左側の決定項はスーパーキーでないといけない、つまり、「X→YにおいてXはRのスーパーキーである」)ということです。
(名前, 目的地, 利用便)の関係について整理すると、
- 候補キーは、{名前, 目的地}・{名前, 利用便}
- {名前, 目的地} → 利用便
- 利用便 → 目的地
です。
利用便 → 目的地は自明な関数従属性ではありません。また、利用便が決定すればデータを特定できるわけではないこともこれまで説明した通りです。利用便というスーパーキーではない属性が目的地に対して従属性があることになります。つまり、このままではボイスコッド正規形にはなりません。
ではどうするかというと、
| 名前 | 利用便 |
|---|---|
| M君 | XX101便 |
| O君 | XX201便 |
| Y君 | XX401便 |
| U君 | XX203便 |
| F君 | XX203便 |
| 利用便 | 目的地 |
|---|---|
| XX101便 | インド |
| XX201便 | 福岡 |
| XX401便 | 沖縄 |
| XX203便 | 福岡 |
という2つの表に分けることで、X→YにおいてXはRのスーパーキーであるという条件を満たし、ボイスコッド正規形に正規化されたことになります。
たしかに第3正規形では、U君とF君の利用便と目的地が同じなので冗長性があったものの、ボイスコッド正規形によりその冗長性が解消されているというメリットがあります。
一方で、ボイスコッド正規形のデメリットについて、1つの表で定義していた場合にはO君は福岡行きの利用便を1つに定めないといけないが、2つの表に分けた場合には{O君, XX203便}というデータを挿入できるため、「福岡に行くのに複数の便を設定できる」という異常な状態を作れてしまうというデメリットがあります。より具体的に説明すると下記となります。
- 1つの表のときは、{名前,目的地}が主キー制約であったため(O君, 福岡, XX201便)(O君, 福岡, XX203便)というデータを主キーによる一意制約違反により持てなかった。
- 2つの表のときは、1つ目の表で(O君, XX201便)(O君, XX203便)、2つ目の表で(XX201便, 福岡)(XX203便, 福岡)というデータを保持できてしまう。
- 結果、第3正規形では同じ人が1つの目的地に行くのに複数の便の設定を制限できたが、ボイスコッド正規形ではその制限ができなくなった。
これを関数従属性損失といい、関数従属性損失が起きないのは第3正規形までのため、日常業務では第3正規形までがよく使われる理由となります。
「そもそも、1つの表でも同じ人が複数の目的地を設定できるのおかしいだろ!」というツッコミは今回は目を瞑ってください・・・。
データベーススペシャリストを受験される方へ
日々の学習お疲れ様です。どの参考書を見ても必ず正規化の話は記載されています。それを理解することも重要ですが、特に午後試験を突破するためには各正規形の理解をするよりも、業務のシチュエーションをERモデリングする力を付けることの方がよほど合格に近づくと思います。ここ最近の試験は論理設計スキルが特に求められているように感じますので日頃から適切にER設計したりデータの流れを想像したりする練習を心掛けていただけると良いのではないでしょうか。健闘を祈っております!
おわりに
KENTEMでは、様々な拠点でエンジニアを大募集しています! 建設×ITにご興味頂いた方は、是非下記のリンクからご応募ください。 recruit.kentem.jp career.kentem.jp