Saturday, October 13, 2007

ある関数従属性をもつ属性に対してどのようなリレーションを作成すべきか?

この投稿、近いうちに削除します。もう少し、うまくまとめて再度アップするつもり。

正規化の議論は、あるリレーションが正しい構造か?更新異常がない構造になっているか?という観点からのもの。ここでは逆に属性をどのように組み合わせていけば正しい構造のリレーションになるかを考えてみる。

まず、2つの属性 A, B は次の3つの関係(リレーションシップ)を持ちうる。

  • 1対1のリレーションシップ。このとき、A → B かつ B → A の関係である。
  • 多対1のリレーションシップ。このとき、A → B かつ B NOT → A の関係である。
  • 多対多のリレーションシップ。このとき、A NOT → B かつ B NOT → A の関係である。


1対1のリレーションをもつとき。

この場合、A と B は少なくとも1つのリレーション R 上に共存しなければならず、A または B が R のキーとなる。A が B を決め、B が A を決めるということは、A と B がそれぞれ何らかのエンティティ・インスタンスを決定していると捉えて、そのリレーションをつくるわけだ。そして、ある属性 C をこの R に追加するには、A → C または B → C が成立しなくてはならない。また、データの不要な重複を避けるために複数のリレーションに A, B が共存することは避けるべき。リレーション間のリレーションシップを作るために A または B が他のリレーションシップに存在する場合はあるが(いわゆる外部キーであろう)、その場合、あるリレーションには A、もう1つのリレーションには B というようにはせず、A または B の1つのみを使うようにした方がいい。

多対1のリレーションをもつとき。

この場合、A と B はリレーション内で共存でき、そのときは A がそのリレーションのキーになる。ある属性 C をそのリレーションに追加できるのは A → C が成立する場合だけ。

多対多のリレーションをもつとき。

この場合、A と B はリレーション内で共存でき、そのとき、(A,B) がそのリレーションのキーになる。(A,B) → C が成立するときだけ C をそのリレーションに追加できる。ただ、(A,B) NOT → C でも、C NOT → (A,B) だとすると、この関係は (A,B) と C との多対多のリレーションシップである。したがって、C をリレーションに追加して、(A,B,C) をキーとできる。ただし、こうしてしまうと、もはやこのリレーションは違う主題を表していることになるので、リレーションの名前を変えた方がよいということになる。

ちなみに、上で C → (A,B) が成立としたら、関数従属性の性質から C → A かつ C → B が成立する。この場合、多対1のリレーションということで、C,A,B が共存することは可能であり、C がそのリレーションのキーということになるだろう。

このように属性を組み合わせてリレーションを作っていけば、それらは DK/NF を満たすようになるだろう。

上の多対多のリレーションで (A,B,C) をキーにする場合だが、こうできるのは、多値従属性 A →→ B | C または B →→ A | C が成立しない場合に限られる。そうでないと 4NF にならず、当然 DK/NF も満たさないから更新時異常が起こってしまう。

たとえば、R{ 教授名, クラス } というリレーションがあって、教授とクラスの組み合わせがキーだとする。授業をする教室が教授の気まぐれで決まるとしたら、使用教室、という属性と (教授名, クラス) とは多対多のリレーションシップをもつ。そして明らかに、ここには多値従属性はないので、{ 教授名, クラス, 使用教室 } をキーとした新しいリレーションをつくることができる。

No comments: