質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.59%

Boyce-Codd正規形について

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 1,568
退会済みユーザー

退会済みユーザー

Boyce-Codd正規形に関連する質問です。
「達人に学ぶDB設計徹底指南書」という本を読んで勉強しています。
Boyce-Codd正規形を満たしていないテーブルとして以下のテーブルが紹介されていました。
以下その本の引用になります。

社員-チーム-リーダー

社員ID   チームコード   チーム補佐
000A 001 123W
000B         001           456Z
000B         002           003O
001F         001           123W
001F         002           003O
003O         002           999Y

このテーブルの意味は次の通りです。テーブルの主キーは、{社員ID、チームコード}です。その意味で、このテーブルは社員とその属するチームの関係を示しています。社員は、複数のチームに同時に所属することができます(社員「000B」のように)。それゆえ、以下のような主キーから非キーへの関数従属性があります。
{社員ID、チームコード} -> {チーム補佐}

一方、このテーブルには、もう一つの業務ルールが存在すると仮定します。それは、「チーム補佐」から「チームコード」に対する関数従属がある、とするという過程です。チーム補佐は、社員を各チームにおいて補佐する役割です。同じチームに複数人いることもありますが、一人が複数のチームを兼任することはできません。つまり、このテーブルには以下のような関数従属も存在するのです。
{チーム補佐} -> {チームコード}
このテーブルには、部分従属及び推移的関数従属はありません。したがって、文句なく第3正規形です。しかし、Boyce-Codd正規形ではありません。というのも、Boyce-Codd正規形とは、「社員-チーム-リーダー」テーブルに見られるような非キーからキーへの関数従属をなくした状態をさすからです。
Boyce-Codd正規形でないと、更新時に次のような問題が生じます。
1. チーム補佐が担当チームを変える場合に複数行の更新が発生する(データの冗長性)。
2. 社員がチームに参加するまで、チーム補佐とチームの関連を登録できない。
3. 社員がチームから外れた時にレコードを削除すると、チーム補佐とチームの関連も削除される危険がある。

こうした不整合を解消する方法が、Boyce-Codd正規形です。
次のようにテーブルを分解することを考えましょう。

社員-チーム

社員ID   チームコード
000A    001
000B      001
000B      002
001F      001
001F      002
003O      002

チーム補佐-チーム

チーム補佐    チームコード
123W 001
456Z                  001
003O                  002
999Y                  002

このように分解すると、どちらのテーブルにも、もう非キーからキーへの関数従属はなくなっていることがわかります。したがって、Boyce-Codd正規形を満たしているように思われます。ところが、この分解には重大な問題があります。試しにやってみればわかりますが、結合のSQL文は、次のようにチームコードを結合キーとして二つのテーブルを結合させるものになります。

SELECT  社員-チーム.社員ID,
        社員-チーム.チームコード,
        チーム補佐-チーム.チーム補佐
  FROM 社員-チーム INNER JOIN チーム補佐-チーム
    ON 社員-チーム.チームコード = チーム補佐-チーム.チームコード;

結果

社員ID    チームコード チーム補佐
-----          ----------             ---------
000A           001                 123W
000A           001                 456W
(以下略)

SQLの結果をよく見てください。
「あれ、元のテーブルよりレコード数が増えている」
そう、この結果には、存在してはならないレコードまで含まれてしまっているのです。これはつまり、「社員-チーム-補佐」の間に、現実には存在しない関連が表現されてしまっている、ということです。

このようにして得られる結果というのは主キーに対して一意性が保証されないため、よくないものだというのはわかるのですが、内容的には問題ないように思えます。
チームコード001で表されるチームというのは123W、及び456Zという二人のチーム補佐がいるわけで、表している内容自体には問題がないと思います。
よって、この結合によって得られた結果のテーブルは、主キーに対して一意性がない、という問題があるためにいけない、ということなのでしょうか?
回答お願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

失われた制約

社員-チーム-リーダー表には以下の制約がありました。

制約(Boyce/Codd正規化により失われた)
{社員ID、チームコード} -> {チーム補佐} 
一つのチームに所属する社員を担当する「チーム補佐はただ一人だけ」である。

表を分割する際にこの制約が失われたのです。

したがってBoyce/Codd正規化は無損失分解ではなく、2つの表を結合すると、
{チームコード}を介して、{社員ID} と{チーム補佐} の直積が現れます。
社員IDは001と001Fがあるので直積の意味がわかると思います。

失われた制約はプライマリキー制約(DDL)ではもはや表せないので、プログラム処理(DML)で補わなければなりません。
・アプリケーションロジック
・トリガー
・SQLのexists制約
・その他のプログラム処理

参考書

増永良文 『リレーショナルデータベース入門 [新訂版]』2003/3 サイエンス社

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/09 23:19

    回答ありがとうございます。
    >失われた制約はプライマリキー制約(DDL)ではもはや表せないので、プログラム処理(DML)で補わなければなりません。

    一般論として、主キーに対する制約でカバーできることがあるということでしょうか?
    また、プログラム処理というのはアプリケーションの方で、例えばこのような結合はしないとかそのような条件を必要とする、という意味でしょうか?

    キャンセル

  • 2016/10/10 07:59

    > 一般論として、主キーに対する制約でカバーできることがあるということでしょうか?
    Boyce-Codd正規化により分解してしまうとできません。

    > プログラム処理というのはアプリケーションの方で、例えばこのような結合はしないとかそのような条件を必要とする、という意味でしょうか?
    そうです。プログラムでなんとかするわけですから、バグが出たり保守性が劣ることが考えられます。

    失われる制約が重要であれば、Boyce-Codd正規化しないという選択肢もあります。

    キャンセル

  • 2016/10/10 15:53

    回答ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る