X（旧Twitter）のデータベース設計をER図で可視化する

## はじめに

今回は、データベース設計の学習のアウトプットとしてX（旧Twitter）のデータベース設計を行い、ER図で可視化しました。

なお、私は以下の教材を使用してデータベース設計、ER図の理解を深めました。

- [スッキリわかるSQL入門 第4版 ドリル256問付き！ (スッキリわかる入門シリーズ)](https://www.amazon.co.jp/dp/4295018465?_encoding=UTF8&psc=1&ref_=cm_sw_r_cp_ud_dp_41830H3PKHPCRHQC2ZD3)
- [達人に学ぶDB設計 徹底指南書](https://www.amazon.co.jp/dp/B00EE1XPAI)
- [小学生でもわかるデータベース設計入門。実際に設計しながら基礎を学ぼう](https://youtu.be/Yg546Zua39A?si=cy5-u31R52Z223Li)
- [データベース入門講座](https://www.youtube.com/playlist?list=PL-1KBX2gDRujQaRgEByueezHBiqHP8KDD)
- [「一対一」「一対多」「多対多」のリレーションを分かりやすく説明する](https://akiyoko.hatenablog.jp/entry/2016/07/31/232754)

## アウトプット

最終的なアウトプットは、次の通りです。
Xのデータベース設計をER図で可視化することができました。

ER図の作成には、[こちら](https://github.com/BurntSushi/erd)のGitHubリポジトリを利用しました。

![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/28d5ddf2-7b19-2a07-6851-d7b376449265.png)

※Xの主要機能のみに絞ってデータベース設計をしています。

### 補足

今回のデータベース設計、ER図の作成は以下の制約のもと行います。

- テーブル名は複数形にすること
- 全テーブルに主キーの`id`を追加すること
- 外部キーカラムは参照するテーブルの単数形のsuffixに`_id`をつける形とすること
- 外部キーは`FK(参照テーブル名）`と書くこと
- 全テーブルに作成日時(`created_at`)と更新日時(`updated_at`)カラムを追加すること
- 一意制約は`uniq`と書くこと

## 作業手順
それでは、データベース設計の流れを書いていきます。
データベース設計の大まかな作業手順は次の通りです。

1. サービスの要件を整理する
2. テーブルの概要設計
3. テーブルの詳細設計
4. ER図として可視化する

## 1.) サービスの要件を整理する

まずは、サービスの画面名ごとにどのような機能が必要になるか表で整理します。なるべく詳細に分かりやすく書いていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/a41599bf-52f7-553a-e233-86b52337cbe9.png)

## 2.) テーブルの概要設計

次に、テーブルの概要設計です。

本工程では、テーブルの一覧とテーブルごとに必要なカラムを洗い出していきます。
簡単に図解してみると、より分かりやすくなるかもしれません。

また、テーブル、カラムを洗い出す際は考慮漏れが起きないよう、ユーザーがサービスを利用する流れ（シナリオ）に沿って洗い出しを行います。

ユーザーがサービスを利用する流れは次の通りです。

1. ユーザーはユーザー登録（サインアップ）画面で、Xにメールアドレスで登録する
2. ユーザー自身のプロフィール情報を登録する
3. ユーザーをフォーローする
4. ツイートする
5. 他ユーザーのツイートをいいね、リツイートする
6. いいね、フォローをされると通知を受け取る
7. ツイートをブックマークする
8. ユーザーは他のユーザーにDMを送信する

以下の通り、シナリオに沿ってテーブルの一覧とテーブルごとに必要なカラムの洗い出しが完了しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/fb21c78b-714e-533a-b2f1-60e93b7051bb.png)

## 3.) テーブルの詳細設計

本工程では、以下を行います。

- テーブルごとのカラムのデータ型と制約を表で整理する
- 簡易的なER図を書きながら、正規化する

### テーブルごとのカラムのデータ型と制約を表で整理する

以下のような形でテーブルごとにカラムのデータ型と制約を表で整理していきます。（添付画像は`users`テーブル）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/9a2bd378-c546-8795-6f76-6d475ec9cf66.png)

### 簡易的なER図を書きながら、正規化する

簡易的なER図を書きながら、テーブル間のリレーションを明らかにします。加えて、正規化も行います。

テーブル間のリレーションを可視化しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/71fc7fc4-e192-dec5-9053-b3b9df835ed6.png)

カラム名を英語に修正し、カラム（主キー、外部キー、`created_at`、`updated_at`）を追加しながら正規化していきます。

本タイミングで追加したカラムは、先ほど（テーブルごとのカラムの型と制約を表で整理する）の表にも忘れずに書いておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/e5b3bca7-a765-0c36-704d-eb9cc91dcfa3.png)

赤矢印の箇所（DM機能）は、多対多のリレーションとなっているため、中間テーブルの追加（正規化）が必要です。

#### DM機能について

ユーザー1人に対して複数のチャットルームを利用する可能性があるため、roomに紐づくuserを管理するテーブル（`entries`テーブル）を新たに作成します。

加えて、userがroomで送信したmessageを新規テーブル（`messeages`テーブル）に切り出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/35e32432-111d-7b63-12c3-06c71259e594.png)

## 4. ER図として可視化する

最後は、好みのツールでER図を作成します。これまで整理した以下情報をER図に反映し、完成です。

- カラムのデータ型、制約
- 主キー、外部キー
- テーブル間のリレーション

![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/aabf9948-58d0-49ed-dbdb-f8e3496e8bf0.png)


## おわりに

初めてER図を作成しましたが、分からないことだらけでした。

ただ、何度も動画や書籍を読み返すことで少しずつ理解し、最終的にER図として可視化することができました。

これからも諦めずに学習を進めていきます。