前回は、IDEF1XによってER図を記述する方法について説明しました。ER図によって記述された概念モデルは、基本的に特定のデータモデルを意識したものではありません。
したがって、概念モデルをリレーショナルモデルとして適切な形式に変換する必要があります。これは、データベース設計においては論理設計の段階にあたります。今回は、概念モデルからリレーショナルモデルに変換する手順について説明します。
多対多の関連
概念モデルでは実体間を多対多の関連として記述することができます。たとえば、「顧客が製品を注文する」ということは、図1のように「顧客」と「製品」という実体間を「注文する」という関連として記述することができます。
このとき、顧客は複数の製品を注文し、製品は複数の顧客から注文されるということであれば、「注文する」という関連は多対多となります。
しかしながら、このような多対多の関連は、データをテーブル(リレーション)として表現するリレーショナルモデルでは取り扱うことができません。
多対多の関連は、Oracleであればコレクション型、PostgreSQLであれば配列型といった特殊なデータ型を使用することによって実現できないこともありませんが、通常、多対多の関連の間に実体を追加し、図2のように「顧客」と「注文」を1対多、「注文」と「製品」を多対1の関連として変換します。
正規形とは
概念モデルから多対多の関連を取り除きさえすれば、実体をテーブルに置き換え、関連を外部キー制約として定義することにより、リレーショナルモデルへの変換を行うことができます。
しかし、そのまま概念モデルからテーブルに変換しただけでは、リレーショナルモデルとして適切な形式にならない場合があります。そこで、正規形と呼ばれるリレーショナルモデルとして適切な形式への変換を行います。なお、テーブルを正規形に変換することを正規化と呼びます。
テーブルを正規形に変換することによって、データの冗長性や不整合の発生を減少させることができます。一言に正規形といってもいろいろなものがありますが、ここでは一般的に適用されている第1正規形や第2正規形、第3正規形について説明します。
正規形について説明するため、例として表1のテーブルを取り上げます。このテーブルは、顧客からの注文に関する情報を格納するもので、「注文番号」が主キーとなります。
第1正規形
第1正規形(First Normal Form;1NF)は、テーブルの列がそれ以上分割できない値のみをもつテーブルのことです。配列やリスト、テーブルの中にテーブルが含まれるような形式で列の値をもつテーブルは、第1正規形ではありません。
たとえば、表1の第1正規形に変換する前のテーブルでは、「製品番号」や「製品名」、「価格」、「数量」といった列の値が1つの行に繰り返し存在しています。そこで、繰り返し存在する列を「注文明細」という別のテーブルとして分割することにより、表2のように第1正規形に変換することができます。
「注文明細」では、分割したテーブルを元に戻せるように「注文番号」を外部キーとして「注文」に関連付けており、「注文番号」と「製品番号」が主キーとなります。
テーブルを第1正規形に変換することにより、リレーショナルモデルとして演算できる対象となります。しかし、テーブルを第1正規形に変換しただけではデータの冗長性が存在しており、それを減少させるには第2正規形、第3正規形へと変換していく必要があります。
第2正規形
第2正規形(Second Normal Form;2NF)は、テーブルが第1正規形であり、なおかつ、主キーである列の値によって主キーではない列の値が一意に特定できるテーブルのことです。
ある列の値によってその他の列の値が一意に特定できるという性質は関数従属性(Functional Dependency;FD)と呼ばれます。なお、複数の列からなる主キーの値が部分的に関数従属性をもつテーブルは、第2正規形ではありません。
たとえば、表2の第2正規形に変換する前のテーブル「注文明細」では、「注文番号」と「製品番号」が主キーとなっています。しかし、「製品名」や「価格」といった列の値は「製品番号」の値のみによって一意に特定することができます。そこで、部分的に関数従属性をもつ列を「製品」という別のテーブルとして分割することにより、表3のように第2正規形に変換することができます。
テーブルを第2正規形に変換することにより、データの冗長性の一部を減少させることができます。たとえば、「注文明細」から「製品」を別のテーブルとして分割すると、それまで「注文明細」に繰り返し出現していた「製品名」や「価格」といった列の値が1行にまとめられます。
第3正規形
第3正規形(Third Normal Form;3NF)は、テーブルが第2正規形であり、なおかつ、主キーではない列が関数従属性をもたないテーブルのことです。
たとえば、表3の第3正規形に変換する前のテーブル「注文」では、「顧客番号」の値によって「氏名」や「住所」、「電話番号」といった列の値を一意に特定でき、主キーではない列が関数従属性をもっています。そこで、関数従属性をもつ列を「顧客」という別のテーブルとして分割することにより、表4のように第3正規形に変換することができます。
テーブルを第3正規形に変換することにより、データの冗長性や不整合の発生をさらに減少させることができます。テーブルを適切に第3正規形に変換すれば、関数従属性に関して不整合が発生することはほぼ解消されます。
なお、正規形にはこの他にも第4正規形や第5正規形、ボイス・コッド正規形といったものがありますが、これらの正規形では関数従属性が保持されないなどといったことから、正規化は一般的に第3正規形までに留めることが多いようです。
今回は、リレーショナルモデルへの変換について正規形に関する説明を中心に行いました。テーブルを正規化する手順や正規形に変換することによって、データの冗長性や不整合の発生を減少できることを、理解してもらえたと思います。
次回からは、データベースとしてオープンソースのPostgreSQLを取り上げ、列のデータ型として何を選択するべきかといったことなど、データベースで実際に管理するために考慮することについて説明していきます。