実際にRDBMSを使ってデータベースを作成する前準備として、どのようなデータベースにするのか、テーブルの作り方や設定を具体的に見ていきましょう。
正規化とは
データベースでは、データを一元管理します。
データを一元管理する手段として、データベースでは、正規化という手法を使います。
正規化は、データの冗長性(繰り返し)を排除し、更新時の整合性を維持しやすくすることを目的としています。
具体的には、繰り返して出てくる無駄なデータを持たないようにし、フィールドとフィールドの関連性を分析して、関連性の強いデータを1つのグループにまとめます。
これにより、データの独立性を高め、グループ化した各表を組み合わせることによって、必要なデータを取り出すことができるようになります。
また、表中のデータを変更した場合にデータ間に矛盾が生じることがないようにします。
正規化には、第1正規化、第2正規化、第3正規化、ボイスコッド正規化、第4正規化、第5正規化の6つの種類があります。
ほとんど場合、第3正規化で事足りるので、ここでは、第3正規化までを取り上げます。
正規化していない表を、非正規形といいます。
非正規形の表を正規化していくことになります。
- 第1正規化
同一の情報のグループが繰り返し出現している部分を分離します。 第2正規化
主キーに注目し、その値が決まれば他の項目もすべて決まるようにします。第3正規化
第2正規形から、主キー以外のフィールドが相互に依存関係をもたないようにします。
具体的には、主キー以外の フィールドを、さらに主キーと外部キーでデータを関連付け、グループに分割し、1つのキーに対して行が1つ決まるようにします。
一覧表を作成する
まず、データベースのテーブル情報の元になる、現実の世界で売上を記録した「受注伝票」を見てみましょう。
上の図は、 2022/2/1 に発生したA商事に対する売上の明細です。
これを、一覧表(表形式)にしていきます。
一覧表を作成するには、各データの意味を明確に示す項目名を付けます。
では、受注伝票の内容を見ていきましょう。
「受注番号」と「注文日」ごとに、1枚の受注伝票が発生します。
2022/2/1に発生した、顧客「A商事」に関する売り上げの明細表です。
顧客に関する情報の項目名は、「顧客番号」「顧客名」「郵便番号」「住所」と付けることにしましょう。
A商事がこの日に注文した商品に関する情報の項目名は「商品番号」「商品名」「単価」「受注数」「金額」とします。
これらの情報をデータベース化するには、まず、最初に洗い出した項目名を使って、一覧表(表形式)を作成します。
それなりの一覧表になりましたが、このような形で作成した一覧表は、注文に関する情報が行方向(横方向)に件数分連なってしまいます。
このままだと多くの注文があった場合、一覧表がどんどん横にのびていきます。
また、1つの注文情報を探すときにも非常に探しづらく非効率的です。
そこで、データベースではこれらの情報を正規化して、扱いやすい形にしていきます。
第1正規化
第1正規化とは、同一の情報のグループが繰り返し出現している部分を分離することです。
はじめに、行方向に延びている表を列方向に移動し、同じ項目ごとにデータを集めます。
1つの顧客に対して何件も繰り返し発生する部分は、「商品番号」「商品名」「単価」「受注数」「金額」になります。
このように、一覧表から繰り返しをなくす作業が第1正規化です。
一覧表から繰り返しをなくしたら、それぞれの表の中で「他の項目から導き出せる項目」を探します。
データベースでは、計算によって導き出される値をわざわざ登録する必要はありません。
注文明細表の「金額」は、「単価」と「受注数」から計算によって導き出すことができるので、「金額」を削除します。
第2正規化
第1正規化をすることで、繰り返しがなくなり一覧表はすっきりしてきましたが、これで完成ではありません。
次に、表の主キーに注目し、その値が決まれば他の項目の値もすべて決まるようにします。
これが第2正規化です。
具体的な手順は次のとおりです。
1. 主キーの一部に、ある項目の値が決まると、それに応じて別の値が一意に決まるものを洗い出し、別の表に分解します。
2. 分解した表の行と元の表の行の関係を維持することができるよう、分解した表のキー項目(外部キー)を定義します。
(関数従属関係のある部分は、別テーブルに分割する)
まずは[一覧表]から注文明細(商品番号、商品名、単価、受注数)を切り離して別のテーブルにします。
ただし、そのまま切り離したのでは、受注番号と商品の関係などが不明になりますので、受注番号と商品番号を連結キーとして分離します。
[注文表]は、「受注番号」が主キーになります。
この値が決まれば、「注文日」や「顧客番号」など、他の値の項目はすべて決まります。
今の段階では、[注文表]をこれ以上分ける必要はありません。
次に、[注文明細表]を見てください。
注文明細表内で、1行を識別する主キーを検討します。
「受注番号」だけでは、同じ値が何度も出てきて行を識別できませんし、「商品番号」だけでも、同じ値が何度も出てくるので行を識別することができません。
それぞれを単独で主キーにすることは不可能です。
そこで、「受注番号」と「商品番号」を組み合わせて主キーにします。
これを、複合主キーといいます。
複合主キーを使って各行を識別する場合、さらに表を分けられる可能性があります。
各行の内容を見てみま しょう。
「受注数」に注目してみます。
「受注数」は「受注番号」だけでは値を特定できませんし、また「商品番号」だけでも値を特定することはできません。
「受注数」は「受注番号」と「商品番号」の組み合わせで値が決まります。
ところが、「商品名」や「単価」は「商品番号」が決まれば、値を特定することができます。
このような主キー以外の項目で値が決まるデータがある場合は、その部分を別の表に分けることができます。
商品に関する表ですので、[商品表]という名前にしておきます。
第3正規化
第3正規化は、主キー以外の項目に注目し、すべての値が主キーの値だけで決まるかどうかを確認し、相互に依存関係を持たないようにします。
[注文明細表]と[商品表]は第2正規化でこれ以上分割する必要はありません。
それでは、[注文表]を詳しく見てみましょう。
[注文表]は、「受注番号」が決まれば、「顧客番号」が決まります。
では、その「顧客番号」に対応する「顧客名」や「郵便番号」「顧客住所」は「受注番号」ではなく、「顧客番号」で決まります。
そこで、顧客の部分を別の表に分けます。
これ以上、表を分割する意味がないので、これで、この伝票の正規化は終わりです。
それでは、受注伝票をもう一度見ておきましょう。
情報を整理するコツ
繰り返して出てくる項目を別の表に分ける
計算で求められる項目は削除する
意味のあるグループごとに表をまとめる
数の表に共通する項目を設定する
共通する項目(主キーになる項目)は、「必ず値が入力される」「値が重複しない」「管理しやすい値」ことが守られている
すべてのデータが主キーの値から決まるようにする
主キー以外の項目から他の項目が導かれないようにする
データ登録時の決まりを作る
リレーショナルデータベースの最大の特徴は、情報を複数のテーブルに分け、それらを組み合わせて利用することです。
その際に用いられるのが、テーブル間で共通の値を持つ項目でした。
このテーブル同士の関連付けに使用される項目は、主キーと外部キーに分けられます。
リレーショナルデータベースでは、主キーと外部キーに大きな役割を持たせます。
主キーと外部キーの設定
主キー:テーブルの中で各レコードの識別に使う項目
リレーショナルデータベースでは、各レコードは重複しないのが大原則です。
主キーをUNIQE(一意)にしておけば、レコードの重複は起きなくなります。
下の表では、1年Aクラスに「鈴木 一郎」という同姓同名の生徒が二人います。
氏名、学年、クラスの情報はまったく同じなので、データが重複してしまいます。
リレーショナルデータベースは重複を原則許可しませんから、このままでは一人分削除するしかありません。
実際には二人いるわけですからそういうわけにはいきませんね。
そこで「生徒NO」という項目を新たに作り、別々の値を振ることで、レコードを区別します。
このようなレコードの識別に使うのが主キーです。
外部キー:テーブルを分けた時に、元のテーブルとの関連付けに使用する項目
外部キーはテーブルとテーブルをつなぐときの共通の項目です。
これまで見てきた受注伝票の表で、主キーと外部キーを整理しておきましょう。
[注文表]の「受注番号」を主キーとし ます。
この主キーにより、[注文表]の各レコードが一意に特定されます。
[注文明細表]は、「受注番号」と「商品番号」を組み合わせた複合主キーによって、受注数が特定されます。
また、[注文明細表]の「受注番号」を外部キーにすることで、受注1件に対する注文明細の1レコードが特定されます。
[注文表]の「顧客番号」は、[顧客表]への外部キーとなり、[顧客表]の「顧客番号」の主キーとして参照することで、顧客の詳細を結合することができます。
[注文明細表]の「商品番号」を外部キーとして、[商品表]の「商品番号」の主キーで結合して、商品の明細を特定します。
主キーと外部キーを設定すると、次のようなルールが自動的に適用されます。
主キーには重複する値やNULL値を登録できない(キー制約:UNIQUE制約、NOT NULL制約)
外部キーには参照先テーブルの主キーに登録されている値しか登録できない(参照整合性制約)
外部キーが使用している値は、参照先テーブルでその値を削除できない(参照整合性制約)
外部キーで使用している値は、参照先テーブルでその値を変更できない(参照整合性制約)
テーブルにおける主キーの設定は必須ではありませんが、このように、主キーと外部キーを使うと、複数のテーブル間で矛盾したデータの登録を防ぐことができます。
参考図書
LINE公式アカウント
仕事が辛くてたまらない人生が、仕事が楽しくてたまらない人生に変わります。
【登録いただいた人全員に、無料キャリア相談プレゼント中!】