【ポートフォリオ開発記】 #2 テーブル作成方法の検討

## テーブルどうやって作成するのが効率的？

**まずはユーザーマスタを作成しよう！**
と思ったのですが、どうやって作成すればいいんでしょうか？

- SQLで作成？
- GUIで作成？
- マイグレーションファイルを作成？

SpringBootで開発するにあたって何を採用したらいいのかが分からなかったので、調べてみました!

## Spring BootでのDBテーブル作成方法（主な3つ）

ChatGPTで質問したところ、以下のような回答が出てきました！

| 方法 | 説明 | 特徴 |
|------|------|------|
| ① エンティティクラス＋自動スキーマ生成 | `@Entity` 定義に基づき、Spring Boot（Hibernate）が自動的にテーブルを作成 | 初学者向き・シンプル・自動で楽だが、本番環境には不向き |
| ② `schema.sql` / `data.sql` の記述 | SQLファイルを手動で用意し、Spring Bootが起動時に実行 | SQLを明示的に管理できる。JPA非依存。 |
| ③ Flyway / Liquibase 等のマイグレーションツール導入 | Laravel同様、バージョン管理付きのマイグレーションを行う | 本番向け、チーム開発向け、堅牢で安全なやり方 |

パッとみた感じ、Flyway / Liquibase というツールを導入するのが良さそうですね。
この二つのツールでよく使われている方を採用したいので、こちらもChatGPTに聞いてみましょう。

### どっちがいい？　Flyway or Liquibase

>✅ 結論：迷ったらFlywayでOK（8割のプロジェクトに十分）

| 条件 | おすすめ |
|------|----------|
| シンプルなSQLでマイグレーションしたい | ✅ Flyway |
| チームが小規模 or 単独開発 | ✅ Flyway |
| YAML/JSON/XMLで定義したい、柔軟な差分検出をしたい | ✅ Liquibase |
| 大規模開発（100人以上など）、DBツールと連携したい | ✅ Liquibase |
| 学習コストを最小限にしたい | ✅ Flyway |

私の場合、ポートフォリオ開発なので
- 単独開発
- 学習コストを最小限にしたい(やり切ることを重視)

の条件に当てはまるので、**Flyway**を採用しましょう！

## Flywayを導入しよう！

ChatGPTに導入方法について確認しながら実際に導入してみます！

### ① 依存関係の追加
pom.xmlに以下の記述を追加します。
```
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
</dependency>
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-mysql</artifactId>
</dependency>
```
>spring-boot-starter-data-jpa を使用していれば、flyway-core はすでに依存関係に含まれている場合があります。

私の環境には存在しないので、追加します。


### ② application.properties に設定追加
application.properties の場合：
```properties
# Flyway設定
spring.flyway.enabled=true
spring.flyway.locations=classpath:db/migration
spring.flyway.baseline-on-migrate=true
spring.flyway.validate-on-migrate=true

# JPA設定
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
```
baseline-on-migrate: true は、既存DBに対してFlywayを初回から適用したい場合に使用。

③ マイグレーションファイルの作成
src/main/resources/db/migration ディレクトリを作成し、そこにマイグレーションSQLファイルを配置します。今回はユーザーテーブルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984442/d3f3b17d-6a04-4d9b-8232-99e9d6f0d632.png)


#### ファイル名規則（重要）
```plaintext
V1__create_users_table.sql
V2__add_email_index.sql
```
ファイル名の形式は V{バージョン番号}__{説明}.sql（ダブルアンダースコア）です。

今回作成したSQLです。
```sql
CREATE TABLE IF NOT EXISTS users (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,      -- ユーザーのユニークID
    username VARCHAR(50) NOT NULL,             -- ユーザー名
    email VARCHAR(100) NOT NULL,               -- メールアドレス
    password VARCHAR(255) NOT NULL,            -- パスワード
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  -- アカウント作成日時
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 最終更新日時
    status ENUM('active', 'inactive', 'banned') DEFAULT 'active', -- ユーザー状態
    UNIQUE (email),                            -- メールアドレスはユニーク
    UNIQUE (username)                          -- ユーザー名もユニーク
);
```
④ 起動時に自動でマイグレーションされる
Spring Boot アプリを起動すると、Flyway が db/migration にある .sql ファイルを実行し、flyway_schema_history テーブルで管理します。


⑤ 作成されているか確認

確認してみたところ、無事作成されていました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984442/6153b1af-e9a7-42d0-b60c-3700f903b1d7.png)


## まとめ
今回はflywayの導入とユーザーテーブルを作成しました。
自分で何を使用して開発するかを決められるのはワクワクして楽しいですね！
アプリが形になるのが待ち遠しいです！