【データベース設計】おばあちゃんでも理解できる【初学者向け】

プログラミング初学者でもデータベース設計の基礎が分かるような記事です。

データベース設計はシステム開発において、とっても重要なので基礎を固めていきましょう！

##データベース設計とは
データベース設計とは、一言でいうと**「データベースに保持するデータの設計」**です。
また、データベースには主に以下の3種類があります。

1.リレーショナルデータベース
2.オブジェクト指向データベース
3.キーバリュー型データストア

この中で一番主流なデータベースは①であり、今回はこれについて買いていきます。

##3層スキーマ
データベース設計では、以下の3層構造が定義されています。
また、3層構造にすることで、どんなメリットがあるのか見ていきましょう。

1.外部スキーマ（ビューなど）
2.概念スキーマ（テーブル定義）
3.内部スキーマ（物理的配置）

データベース全体を一気に定義することは大変なので、3層に分けてそれぞれ定義していこう、という考え方ですね。

そして3層スキーマを用いるメリットは、**変更に柔軟に対応できる**ということです。
例えば、ユーザーの見た目を変更したいとしましょう。
このとき、3層構造になっていなければ、データベースの変更がデータベース設計全体に影響してしまい大変です。
ここで3層スキーマにすることで、ひとつのスキーマに変更があったとしても他のスキーマには影響しない状態を作り出すことが可能なのです。

##データベース設計の流れ
リレーショナルデータベースの設計の流れとしては以下のようになる。

**1.論理設計**
概念スキーマの設計
データを管理するためのデータモデルの設計
**2.物理設計**
内部スキーマの設計

そして今回学ぶ論理設計に関しては、以下のステップから構成されています。

**1.エンティティの抽出**
どんなデータを管理するエンティティ（テーブル）が必要かを考える
**2.エンティティの定義**
そのエンティティにおいてどのような属性が必要か考える
**3.正規化**
データの冗長性を排除し、一貫性や効率性を保持するようなデータ形式になる形でテーブルを定義
**(4.ER図作成)**
エンティティごとの関係を作図する

それでは、一つ一つのステップを詳しく見ていきましょう！

##エンティティとは
そのまえに、エンティティについての理解を深めておきましょう。
エンティティとは、**システムにおいて管理する必要があるデータ**のことを言います。

具体的にはある商品のデータがあるとします。
この商品データの中には、「商品名」「原産国」「仕入先ID」「商品カテゴリ」などの属性が含まれています。
この商品そのもののデータをエンティティと言い、ER図で表すところの一つの箱を表します。<img width="788" alt="スクリーンショット 2020-05-30 22.45.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618902/1683d1b0-9d43-00a1-af62-e1408bb5cfeb.png">
[出典]https://it-koala.com/entity-relationship-diagram-1897

##1.2.エンティティの抽出・定義
**エンティティの抽出**
システムにおいてどのようなエンティティが必要かを考えます。
例えばお店の予約サイトを作成しようとすると、顧客情報を管理する**「顧客」**のデータと、予約を管理する**「予約」**のデータ、店舗情報を管理する**「店舗」**のデータが必要だと考えます。

**エンティティの定義**
各エンティティがどのような属性を持つのかを決めます。
先ほどの例における「顧客」を挙げてみると、顧客の**「名前」「年齢」「住所」「電話番号」「メールアドレス」**などが考え得る属性（カラム）となるわけです。

##3.正規化
リレーショナルデータベースにおけるエンティティを整理するプロセスです。
具体的には、データベースにおける重複するデータを排除していくということですね。

これはテーブルを正規形に整えるともいい、正規形には第1〜5正規形が存在します。
一般的には第3正規形までを考えます。

##第1正規形
第1正規系とは、**1つのフィールドには1つの値しか含まない**という原則が守られた形にすること。
つまり、1つの行の中に複数の行（データ）がある状態を、1つの行に1つの行という構成に直す作業です。

下の写真を参考にすると、正規化する前は「cinema_code」が7のデータにおいて、staffデータが2つ格納されています。
これはNGなので、staffデータを別々の行に直したものが第一正規化です。

※ここではこのような第1正規形を行いましたが、テーブルを2つに分けて正規化する方法もあります。**データがNULL**になってしまい、主キーを定めることができないようなときに用います。
<img width="511" alt="スクリーンショット 2020-05-31 0.21.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618902/89f3b235-676a-2ee2-caca-ece125e1e089.png">
[出典]http://ext-web.edu.sgu.ac.jp/HIKO/Prog03/SenpaiKyozai/shiohara/formalize.html

**関数従属制**
ここで正規化において重要な考え方を述べておきます。それは関数従属制です。
なにかというと、**一方の値が決まると他の項目の値も一意に決まる関係**です。

具体的な例をあげると、y=f(x)のように、あるxの値が与えられるとき、yの値も決まる関係性ですね。
このとき、yはxに従属するといい、{x}→{y}という記号で表します。

これを踏まえて正規化とは、**「テーブル全ての列が関数従属制を満たすように整理していくこと」**であり、{主キー}→{カラム}が全てのカラムにおいて成立している状態にすることをいいます。

##第2正規形
第2正規形とは、**部分関数従属が解消されていて、完全関数従属のみのテーブルになっている形にする**こと。

部分関数従属とは、主キーの一部によって値が決定する関係をいい、完全関数従属とは、主キーを構成する全ての列に対して値が決定する関係をいいます。

具体的に下の図で説明すると、cinema_codeという主キーが決まれば、矢印が向いている4つの属性の値が決定します。
この状態を部分従属しているといい、主キーに部分従属している属性を分離する作業が第2正規形です。
<img width="405" alt="スクリーンショット 2020-05-31 0.58.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618902/0336e708-bc45-51b9-7fa3-c34306260bf9.png">

この図を第2正規形にしたものがこちらです。
cinema_codeとstaff_codeという異なるレベルのエンティティを分離しました。
<img width="511" alt="スクリーンショット 2020-05-31 1.04.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618902/df12524b-8e5c-f39a-62af-e7631a92f476.png">
[出典]http://ext-web.edu.sgu.ac.jp/HIKO/Prog03/SenpaiKyozai/shiohara/formalize.html

##第3正規形
第3正規形とは、**推移的関数従属が解消されている形にする**こと。
まず推移的関数従属とは何かを説明します。

**推移的関数従属**
推移的関数従属は一言で言えば、**2段階の関数従属がある状態**です。
下の図を具体的に見てみます。
Genre_codeが決まればGenre_nameが決まる関数従属制が成立しています。
また、cinema_codeが決まれば、Genre_codeが決まるという関数従属制も成立しています。
よって記号で表すと、**{cinema_code}→{Genre_code}→{Genre_name}**という2段階の関数従属が成り立っていることが分かります。
これを推移的関数従属と言います。
<img width="294" alt="スクリーンショット 2020-05-31 1.49.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618902/628a52c5-27b8-7dce-b0b7-72c835055768.png">

これを踏まえて、推移的関数従属を解消します。
下のようにGenreエンティティを分離して作成することで推移的関数従属を解消することができます。
また分離することで、Genreに格納されている全てのデータを確認できるようになりました。
これも第3正規形の大きなメリットとも言えます。
<img width="420" alt="スクリーンショット 2020-05-31 1.57.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618902/e537b379-16d5-e60a-4147-e6b2d23840bb.png">
[出典]http://ext-web.edu.sgu.ac.jp/HIKO/Prog03/SenpaiKyozai/shiohara/formalize.html

##4.ER図作成
あとは作成したテーブルを元にER図を作成するだけです。
ER図に関してはこちらの[5分で理解できるER図の書き方5ステップ](https://it-koala.com/entity-relationship-diagram-1897)が分かりやすいので参考にしてみてください。
また、YouTube等にも動画がありますので、そちらも参考にしてみるといいかもしれませんね。