データベース設計初心者がER図について調べてみた！〜dbdiagram〜

# はじめに
私は現在実務未経験でiOSエンジニアになるため、Swiftをメインに学習を行っています。以前Go言語でAPI開発を行ったことがありますが、データベース設計を事前に考えられていなかったためiOS側でAPIをたたいた時に困ったことがあります。
それをER図を作成し、データベース設計をじっくり考えることで解決するのではないかと思い、ER図について調べてみました。

# ER図とは
ER図とはEntity Relationshipの略です。日本語訳すると「Entity = 実体、Relationship = 関係」です。実体同士の関係を図に表したのが、ER図という認識です。

# ER図作成ツール
dbdiagram.ioとはコードを書くだけでER図を描画できる無料のシンプルなツールです。

https://dbdiagram.io/home

実際にdbdiagram.ioを使用してER図を書いてみる。

![9ffb219f2f6026a2eed4d7f6575a3355.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090887/444db157-e493-f704-eda3-d7e7beb0d0ea.png)

dbdiagramで下記のようにテーブルを作成してみました。
```dbdiagram:dbdiagram.io
Table accounts as A {
  id bigserial [pk]
  owner varchar [not null]
  balance bigint [not null]
  currency varchar [not null]
  created_at timestamptz [not null, default: `now()`]

  Indexes {
    owner
  }
}

Table entries {
  id bigserial [pk]
  account_id bigint [ref: > A.id, not null]
  amount bigint [not null, note: 'can be negative or positive']
  created_at timestamptz [not null, default: `now()`]

  Indexes {
    account_id
  }
}

Table transfers {//2つの口座間のすべての送金を記録
  id bigserial [pk]
  from_account_id bigint [ref: > A.id, not null]
  to_account_id bigint [ref: > A.id, not null]
  amount bigint [not null, note: 'must be positive']
  created_at timestamptz [not null, default: `now()`]

  Indexes {
    from_account_id
    to_account_id
    (from_account_id, to_account_id)
  }
}
```
## ER図のエクスポート
作ったER図からPDF・PNG・SVG・MySQL・PostgreSQL・SQL Server・Oracle SQLなど各種形式でエクスポートが可能です。
上記のER図をMySQLにエクスポートすると下記のコードを自動生成してくれます。
```MySQL:MySQL
CREATE TABLE `accounts` (
  `id` bigserial PRIMARY KEY,
  `owner` varchar(255) NOT NULL,
  `balance` bigint NOT NULL,
  `currency` varchar(255) NOT NULL,
  `created_at` timestamptz NOT NULL DEFAULT (now())
);

CREATE TABLE `entries` (
  `id` bigserial PRIMARY KEY,
  `account_id` bigint NOT NULL,
  `amount` bigint NOT NULL COMMENT 'can be negative or positive',
  `created_at` timestamptz NOT NULL DEFAULT (now())
);

CREATE TABLE `transfers` (
  `id` bigserial PRIMARY KEY,
  `from_account_id` bigint NOT NULL,
  `to_account_id` bigint NOT NULL,
  `amount` bigint NOT NULL COMMENT 'must be positive',
  `created_at` timestamptz NOT NULL DEFAULT (now())
);

CREATE INDEX `accounts_index_0` ON `accounts` (`owner`);

CREATE INDEX `entries_index_1` ON `entries` (`account_id`);

CREATE INDEX `transfers_index_2` ON `transfers` (`from_account_id`);

CREATE INDEX `transfers_index_3` ON `transfers` (`to_account_id`);

CREATE INDEX `transfers_index_4` ON `transfers` (`from_account_id`, `to_account_id`);

ALTER TABLE `entries` ADD FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`);

ALTER TABLE `transfers` ADD FOREIGN KEY (`from_account_id`) REFERENCES `accounts` (`id`);

ALTER TABLE `transfers` ADD FOREIGN KEY (`to_account_id`) REFERENCES `accounts` (`id`);
```

# おわりに
データベース設計についての基礎の理解を深めることでiOSエンジニアとして実務に着いた時、バックエンドの方々とデータベース設計について議論できるように今後も学習していきたいです。

# 参考文献
https://www.udemy.com/course/backend-master-class-golang-postgresql-kubernetes/?srsltid=AfmBOopZ_8Z-NraZaclH-gGTUcBkkmzG7oRWnCgSzRfpMtM4WFYYOGgY

https://docs.dbdiagram.io/release-notes/2019-07-index-for-table

https://zenn.dev/ryo_kawamata/articles/introduce-ddbdiagram-io

https://tech-lab.sios.jp/archives/41457