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正規形でないと、更新時に次のような問題が生じます。
- チーム補佐が担当チームを変える場合に複数行の更新が発生する(データの冗長性)。
- 社員がチームに参加するまで、チーム補佐とチームの関連を登録できない。
- 社員がチームから外れた時にレコードを削除すると、チーム補佐とチームの関連も削除される危険がある。
こうした不整合を解消する方法が、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文は、次のようにチームコードを結合キーとして二つのテーブルを結合させるものになります。
SQL
1SELECT 社員-チーム.社員ID, 2 社員-チーム.チームコード, 3 チーム補佐-チーム.チーム補佐 4 FROM 社員-チーム INNER JOIN チーム補佐-チーム 5 ON 社員-チーム.チームコード = チーム補佐-チーム.チームコード;
結果
社員ID チームコード チーム補佐
000A 001 123W
000A 001 456W
(以下略)
SQLの結果をよく見てください。
「あれ、元のテーブルよりレコード数が増えている」
そう、この結果には、存在してはならないレコードまで含まれてしまっているのです。これはつまり、「社員-チーム-補佐」の間に、現実には存在しない関連が表現されてしまっている、ということです。
このようにして得られる結果というのは主キーに対して一意性が保証されないため、よくないものだというのはわかるのですが、内容的には問題ないように思えます。
チームコード001で表されるチームというのは123W、及び456Zという二人のチーム補佐がいるわけで、表している内容自体には問題がないと思います。
よって、この結合によって得られた結果のテーブルは、主キーに対して一意性がない、という問題があるためにいけない、ということなのでしょうか?
回答お願いします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2016/10/09 14:19
退会済みユーザー
2016/10/09 22:59
退会済みユーザー
2016/10/10 06:53