【DB/データベース設計】自分なりの手順 ~論理設計編~

データベース設計について復習したのでメモを書いていきます。
主に下記書籍を参考にしています。
[楽々ERDレッスン](https://www.amazon.co.jp/%E6%A5%BD%E3%80%85ERD%E3%83%AC%E3%83%83%E3%82%B9%E3%83%B3-CodeZine-BOOKS-%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF-%E7%BE%BD%E7%94%9F/dp/4798110663/ref=cm_cr_arp_d_product_top?ie=UTF8)
[達人に学ぶDB設計 徹底指南書](https://www.amazon.co.jp/dp/B00EE1XPAI/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

## データベース設計
主に下記2つに分解することができます。

1. 論理設計
2. 物理設計

## 論理設計
1. エンティティの抽出
2. エンティティの定義
3. 正規化
4. ER図の作成
5. 実際に値を入れ、ユースケースに耐えうるか確認

### 論理設計の重要な要素
- 正規化
- インデックス設計

### エンティティの抽出
下記書籍の「病院の受付伝票」を例に進めます。
まあ患者さんが診察をするために受付をするくらいのイメージです。
[楽々ERDレッスン](https://www.amazon.co.jp/%E6%A5%BD%E3%80%85ERD%E3%83%AC%E3%83%83%E3%82%B9%E3%83%B3-CodeZine-BOOKS-%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF-%E7%BE%BD%E7%94%9F/dp/4798110663/ref=cm_cr_arp_d_product_top?ie=UTF8)

#### ブロックに分ける
上記例の場合、「患者」、「受付」などがメインのテーブルとしてあげられるでしょう。
このくらいの粒度でざっと分けてみます。

#### イベント系、リソース系エンティティの整理
**イベント系エンティティ**
**「~する」と言えるかどうか**で決まるエンティティです。
**どのように**に当てはまります。
具体例でいうと、受付するとか、診察するとかです。

**リソース系エンティティ**
**「~する」と言えないものは**、こちらに属します。
**誰に、誰が、何を、どこ**に当てはまります。
具体例でいうと、患者とか、担当医師などです。

整理するとわかりますが、リソース系エンティティがわりかし多く、イベント系エンティティはそこまで多くないことがわかります。

### 正規化
イベント系、リソース系エンティティの重複しているものなどがないかチェックします。
この正規化で必要な過程として、**可逆性**も担保できるようにしておきます。
あとで検索できるかどうかです。

#### インデックス設計
>作るとデータ参照が速くなるやつ
[MySQLでインデックスを貼る時に読みたいページまとめ(初心者向け） - Qiita](https://qiita.com/C058/items/1c9c57f634ebf54d99bb) より引用

詳細は下記記事などが参考になります。
[MySQLパフォーマンスチューニングのためのインデックスの基礎知識 - 久保清隆のブログ](https://kiyotakakubo.hatenablog.com/entry/20101117/1289952549)
[MySQL :: MySQL 5.6 リファレンスマニュアル :: MySQL 用語集](https://dev.mysql.com/doc/refman/5.6/ja/glossary.html#glos_b_tree)
[PostgreSQLでインデックスを効率良く利用しよう \| TECHSCORE BLOG](https://www.techscore.com/blog/2014/12/04/postgresql%E3%81%A7%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9%E3%82%92%E5%8A%B9%E7%8E%87%E9%AB%98%E3%81%8F%E5%88%A9%E7%94%A8%E3%81%97%E3%82%88%E3%81%86/)
[パフォーマンスを考慮したIndex定義設計 \| TECHSCORE BLOG](https://www.techscore.com/blog/2019/12/25/performance_index/)

#### 正規化とパフォーマンスの関係性[参考]
正規化すればするほど、整合性は担保できるが、パフィーマンスは落ちてしまう傾向があります。


### ER図作成
#### 何で書くか
下記のいづれかがおすすめです。

- [Flowchart Maker & Online Diagram Software](https://app.diagrams.net/)
- [lucidchart](https://app.lucidchart.com/)

### ユースケースに耐えうるか実際の値を入れて確認
スプレッドシートとかに実際に入るであろう値を入れていき、実装する機能を実現できるかを確認します。
この時に懸念事項があれば、エンティティの再確認、ER図修正などを行ったりします。

### 主なチェックリスト
- テーブル名は英語ならば複数形/複数名詞で書けるか
- 日本語を使っていないか
- 最初はアルファベットになっているか(test_2020のようにすべき)
- テーブル名は同じドメイン内で重複していないか
- 複数のテーブルをまとめていないか
- 主キーにidという名前を利用していないか
- 参照整合性制約をつけているか
- NOT NULL 制約はなるべくつけているか

[4ステップで作成する、DB論理設計の手順とチェックポイントまとめ - Qiita](https://qiita.com/nishina555/items/a79ece1b54faf7240fac) より引用


### 参考記事
[4ステップで作成する、DB論理設計の手順とチェックポイントまとめ - Qiita](https://qiita.com/nishina555/items/a79ece1b54faf7240fac)
[SQLアンチパターンもりもりDBを設計しよう！ - Qiita](https://qiita.com/Mister_K/items/ff4c63085ecd9e77fa33)
[DB論理設計のノウハウ - Qiita](https://qiita.com/kiyodori/items/5083ad8bbfc232d01827)


## 物理設計
1. テーブル定義
2. インデックス定義
3. ハードウェアサイジング
4. 冗長構成
5. ファイルの物理配置

[「データベースをつくってみよう！」 データベース物理設計-入門編](https://www.oracle.com/technetwork/jp/ondemand/database/db-basic/dbphysicaldesign-1524122-ja.pdf)
[第５章 データベースの物理設計](https://www.ibm.com/developerworks/jp/data/library/dataserver/pdf/db2potdba_session5.pdf)

インフラに関わる部分が多いです。

## TODO
### RDBかNoSQLか
そもそもデータベース設計に入るまでに、RDBが良いのか、それともNoSQLが良いのかはこれから判断基準を自分の中に落とし込んでいきたいなと思っています。

#### 全体図
まずNoSQLが全体のどこに位置するのかは下記が非常にわかりやすい
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148392/af2d58c8-e8a3-5fa6-d33b-cde538b05d60.png)
[RDB技術者のためのNoSQLガイド　NoSQLの必要性と位置づけ](https://www.slideshare.net/recruitcojp/rdbnosqlnosql) より引用

[NoSQLとRDBMSの違いが分かる3分Q&A - Qiita](https://qiita.com/kubocchi/items/e123cffc518c402b399b)