データベース設計の基本

『OSS教科書　OSS-DB Silver Ver.2.0対応』（翔泳社）
こちらの書籍のデータベースの設計についての部分を読んだので、こちらを元にデータベース設計の基本について、学習のアウトプット目的でまとめます。

サービス化（データベース化）する対象世界を０からテーブル作成を行える形にするまでの考え方や手順を順序立てて書いています。

# データモデル

データベースを構築する対象の範囲を**対象世界**と呼びます。
**データモデル**とは、対象世界をモデル化したものを指します。

データモデルには、対象世界を抽象化した**概念データモデル**と、その概念データモデルをデータベースで実装可能な形にした**論理データモデル**があります。
（後でそれぞれについて具体的にまとめています）

概念データモデルと論理データモデルを作成する手順は次のようになります。

1. 対象世界から概念データモデルを抽象化する
2. 概念データモデルから論理データモデルに変換する


![データベース設計 - シート1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/453b7746-84d5-125e-8513-e8e1d6aa273e.png)


## 概念データモデル

概念データモデルは、対象世界を抽象化して、対象世界のデータ構造を概念的に捉えた結果を表現したモデルです。

![データベース設計 - シート1 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/8184420b-3bd6-e6a5-9e90-eaf1e666ae07.png)

概念データモデルの作成はERモデル（ER図）で行います。

ERモデルとは、上図右側のような、実体同士を線でつなげた図です。

Entity（実体）とRelationship（関連）によって作成するのでERモデルと呼ばれます。

Entityは、管理対象とするデータの集合体を指します。
Relationshipは、Entity間のつながりを指します。

* 例１）売上の単位で出荷がある場合（売上１に対して出荷が１の場合）：１対１

![空白の図 - データベース ER 図 (カラスの足記法) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/77c29bf9-2951-85cd-6e30-6fa739a2ce7b.png)

* 例２）各部門に複数の社員が所属し、社員は１つの部門のみに所属する場合：１対多

![空白の図 - データベース ER 図 (カラスの足記法) (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/ba3bf550-924c-f739-6c27-00f73df358a2.png)

* 例３）製品は複数の部品で構成され、同じ部品が複数の製品で利用される場合：多対多

![空白の図 - データベース ER 図 (カラスの足記法) (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/bcd486e0-7f0f-66d8-8c2b-913ad18e897f.png)

すなわち、概念データモデルとは、対象世界のデータをER図に起こしたものを指します。

この段階ではまだ、特定のデータベースに依存しないため、データベースでテーブルを作成して実装することはできません。
データベースで実装可能にするために論理データモデルに変換します。

## 論理データモデル

論理データモデルは、データとデータ間の関係を論理的に表したもので、そのままデータベースとして実装可能なデータモデルとなっています。

論理データモデルの種類には、歴史的に「階層モデル」、「ネットワークモデル」、「関係モデル」などがありますが、リレーショナルデータベースシステムでは**関係モデル**を使います。

### 関係モデル

関係モデルは、関係（リレーション）と呼ばれる表構造でデータを表現します。（以下画像）
![スクリーンショット 2022-10-12 8.10.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/a53c98e9-2a4f-ee8e-78cd-5f509e7735ad.png)

関係モデルの構成要素の名称は次のように呼ばれるようです。

* 行：タプル（組、ロー）
* 列：アトリビュート（属性、カラム）

（個人的に現場では行と列としか聞いたことがないです）

# データベース設計

データベース設計は次の手順で行います。

1. 概念データモデルを作成する（ER図を作成）
2. 導入するデータベースマネジメントシステムに合わせて論理データモデルに変換する（関係モデルを作成）

## 概念データモデルの作成

最初に、管理対象とするデータを対象世界から抽出し、Entityとして定義します。
抽出するデータは、実体が物理的に存在するデータだけでなく、実体が存在しないデータも含めて検討します。

* 商品、取引先などのように、実体が物理的に存在するデータ（例：部門）
* 売上、出荷などのように、実体が存在しないデータ（例：社員）

概念データモデルを作成する上でポイントとなるのは、「対象世界はどうあるべきか」、「対象世界ではどのようなデータを保持すべきか」という点です。

例えは、「部門」と「社員」のつながりを考えます。
部門を視点とすると、「１つの部門には複数の社員が入るのか」「１人も社員が属していない部門があってもいいのか、よくないのか」など。
社員を視点とすると、「社員は必ずどこかの部門に属すのか、属さなくてもいいのか」「１人の社員は１つの部門にしか属さないのか、複数の部門に属すこともあるのか」など。

## 論理データモデルへの変換

ER図を作成したら関係モデルに変換します。基本的にER図の１つのEntityが関係モデルの１つの表（関係）に対応します。

ただし、「多対多」のRelationshipがある場合、そのままでは関係モデルとして扱うことはできません。
解消する方法としては、多対多の間に新たなEntity（連関Entity）を作成し、「１対多」と「多対１」のRelationshipにすることで関係モデルを作成します。

# 正規化

多対多の関係を解消した関係モデルであっても、データベースにそのまま実装すると、データの更新によって、冗長なデータが発生したり、不整合が生じたり、データが失われたりするなど、不整合が発生する場合があります。

データベースに発生する不整合を**更新時異常**と言います。

更新時異常が発生しないようにするために、関係を**正規化**します。

## 更新時異常

登録時
丸山太郎さんが複数回注文すると、丸山太郎さんについて同じ情報を何度も登録しなければならない。

![スクリーンショット 2022-10-12 7.57.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/900351da-2079-a622-188e-6d4fa7628854.png)

更新時
丸山太郎さんが新宿区神楽坂から中央区日本橋へ転居した場合に顧客住所の更新漏れが発生するとデータの不整合になる。

![スクリーンショット 2022-10-12 8.00.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/91962540-d25d-7540-5fc3-40caa3b4d2a2.png)

削除時
丸山太郎さんが注文を取り消した時に売上情報を削除すると、丸山太郎さんの情報そのものも削除されてしまう。

![スクリーンショット 2022-10-12 8.03.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/6d9f1b8e-8ca2-983c-7db4-3fc356e2ede0.png)


## 候補キーと主キー

正規化を行うときは**主キー**を決める必要があります。
主キーを決めるには、まず候補キーを明確にします。候補キーとは、行を一意に識別できる単独の属性、もしくは必要最小限の属性の集合です。

主キーにはNULLを含めることができません。（NOT NULL制約）

## 非キー属性

非キー属性とは、いずれの候補キーにも含まれない属性です。

## 関数従属

正規化を行うには、関数従属という性質に注目します。
関数従属は属性間の性質で、Xの値が決まれば別の属性Yの値がただ１つ決まる場合、「属性Yは属性Xに関数従属する」と言います。

## 非正規形

![スクリーンショット 2022-10-12 7.10.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/410b6cc1-4239-240d-2937-237875611a06.png)


## 第一正規形

![スクリーンショット 2022-10-12 7.19.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/4178ba83-9a68-1a37-b8ca-cd890aa95e69.png)


## 第二正規形

![スクリーンショット 2022-10-12 7.28.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/e265ae8b-89b7-387b-3e0d-ddf0bc096221.png)


## 第三正規形

![スクリーンショット 2022-10-12 7.33.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/0e31ce6e-9978-ea5f-24b8-bf22eefc976f.png)


## ボイスコッド正規形

![スクリーンショット 2022-10-12 7.39.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608177/59e63c98-02ea-ed52-16c7-4f9d72da6f94.png)