MySQL
SQLite3
データベース
データべース設計

データベースの正規形について考える

More than 1 year has passed since last update.

はじめに

システムを作っていく上でデータベースの設計は避けては通れません。
といっても、どうするのがベストなのか、どう折り合いをつけるべきなのか悩むところです。
そこで、データベースには「正規化」というものがあります。
たぶん、基本的には「第3正規形」が一般的に使われていると思います(たぶん)
今回は、その第3正規形について説明していきたいと思います。

正規化とは

正規化とは簡単に言うと「効率よくデータを扱うため、データを整理すること」です。
詳しく言うと
・データの重複をなくして、整合的にデータを取り扱えるようにデータベースを設計すること。
・データの追加・更新・削除のときに不整合が起こるのを防ぎメンテナンスをしやすくする。
ってことです。

第1正規形

例えば、卸売会社で商品を以下のような形で管理しているとします。

仕入先 住所 代表者 代表者連絡先 商品名 単価 入荷日 入荷数 備考
X商社 A県B市 Y田S男 03-xxxx-yyyy メモリ 5000 2017-08-30 10 S社製
X商社 A県B市 Y田S男 03-xxxx-yyyy CPU 30000 2017-05-30 3 I社製
Y商社 C県D市 K田J子 03-gggg-dddd HDD 10000 2017-07-30 10  

これは、すべて個別のデータとなっているため、レコードとして登録できます。
この状態が「第1正規形」です。基本的な形ですね。

しかし、これにはいくつか問題があります。

・もし新しい仕入先が増えたとしても、実際にその仕入先から仕入れないと登録できない
・代表者や連絡先などが変更になった場合、複数レコード修正する必要があり不整合が起きやすい

などがあります。

主キーと非主キー

ここで、データベースを設計するために知っておく必要がある「主キー」と「非主キー」について説明します。

image.png

主キーとは、「第1正規形のテーブルでレコードを一意に定める要素」である。つまり、「仕入先、商品名、入荷日」である。なので、非主キーとはそれ以外の項目であり、非主キーは主キーの一部の要素で決まります。これを部分関数従属といいます。

言い換えると、「仕入先」「商品名」「入荷日」のそれぞれのテーブルを作成し、リレーションを組むことができます。これが「第2正規形」です。
では、第2正規形に整形します。

第2正規形

・仕入先テーブル

仕入先 住所 代表者 代表者連絡先
X商社 A県B市 Y田S男 03-xxxx-yyyy
Y商社 C県D市 K田J子 03-gggg-dddd

・入荷テーブル

商品名 仕入先 入荷日 入荷数
メモリ X商社 2017-08-30 10
CPU X商社 2017-05-30 5
HDD Y商社 2017-07-30 5

・商品テーブル

商品名 単価 備考
メモリ 5000 S社製
CPU 30000 I社製
HDD 10000

さて、これで「第2正規形」に整形できました。第1正規形に比べて、メンテナンスもしやすくなりました。
しかしそれでも、代表者が複数の仕入先にいた場合に、代表者連絡先などが変更されたら、複数のレコードを変更する必要があります。
なので、主キー以外でも依存関係を持っているもの(推移的関数従属)も、別テーブルに切り分けていきたいと思います。
これが、「第3正規形」です。

第3正規形

・仕入先テーブル

仕入先 住所 代表者 代表者連絡先
X商社 A県B市 Y田S男 03-xxxx-yyyy
Y商社 C県D市 K田J子 03-gggg-dddd

・入荷テーブル

商品名 仕入先 入荷日 入荷数
メモリ X商社 2017-08-30 10
CPU X商社 2017-05-30 5
HDD Y商社 2017-07-30 5

・商品テーブル

商品名 単価 備考
メモリ 5000 S社製
CPU 30000 I社製
HDD 10000

・電話帳

代表者 代表者連絡先
Y田S男 03-xxxx-yyyy
K田J子 03-gggg-dddd

第3正規形にすれば、基本的には1つの要素を変更すれば、リレーションを組んでいるので自動的に複数レコード変更されます。メンテナンスも楽ですし、不整合も出にくいので、それが第3正規形のいいところですね。

まとめ

正規形としては、第1から第5まで存在しますが、第4, 5はよほどのことがない限り使いません。
なぜなら、逆に複雑になりすぎるからです。基本的には第3正規形が完成だと思っても大丈夫だと思います。

わかりやすく、かつ、メンテナンスが楽・不整合が起こらない管理方法が一番です。