294日目　Entity、Seed、Migrationについて簡単に説明する社畜M

## ♠はじめに
こんにちは、社畜Mだぜ。 
今回は開発作業で出てくる概念、「**エンティティ(Entity)、シード(Seed)、マイグレーション(Migration)**」について語らせてもらうぜ！データベースを扱う開発なら必ずと言っていいほど触れることになるこれらの概念。 しっかり理解しておかないと、開発中に「これ何だっけ？」となること必至だからな！

さぁ、行くぜ！！！
**デュエル！**
## ♠エンティティ、シード、マイグレーションとは？
まずは、それぞれの概念について簡単に説明していきます。

### ♦エンティティ（Entity）とは
エンティティとは、簡単に言えば「**データベースのテーブルをプログラム上で扱いやすくしたもの**」です。
オブジェクト指向のプログラムでは、データをオブジェクトとして扱うことが一般的で、データベースの各テーブルに対応するクラス（オブジェクト）がエンティティと呼ばれます。

#### ♥ エンティティの具体例
たとえば、社員情報を管理するデータベースがあったとすると、このデータベースには、次のようなテーブルがあるかもしれません。
| **社員ID** | **氏名** | **年齢** | **部署** |
|--------------|--------------|--------------|--------------|
| 1        | 田中太郎        | 30        | 開発部        |
| 2        | 山田花子        | 28        | 営業部       |

このデータをプログラム上で扱うためには、エンティティクラスを作る必要があります。
TypeScript（NestJSなどのフレームワーク）を例にすると、こんな感じになりますね。

```:TypeScript
import { Entity, PrimaryGeneratedColumn, Column } from '********';

@Entity()
export class Employee {
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    name: string;

    @Column()
    age: number;

    @Column()
    department: string;
}
```
あくまで例えで作りましたが、上記のコードでは、Employee クラスが「社員」テーブルを表すエンティティになっています。
@Entity() をつけることで、このクラスがデータベースのテーブルと関連していることを示します。
カラムの定義も、@Column() を使ってデータベースのカラムに対応させています。


### ♦シードとは？
シードとは、簡単に言えば「**あらかじめ用意しておく初期データ**」のことです。
データベースを構築した直後は空っぽの状態ですが、アプリケーション開発の中では
「最低限必要なデータが最初から入っていてほしい！」ということがよくあります。
たとえば、管理者ユーザーやデフォルトの設定データなどがそれに当たります。

#### ♥ シードの具体例
シードを作成する方法はフレームワークによって異なるが、TypeScriptを例にすると、次のようなコードでデータを初期登録できます。
```:TypeScriptのSeed
import type { SeedRecord } from '********';
import { BaseCdSeed } from '**********';
import { Employee } from '**********';

export default class EmployeeSeed extends BaseCdSeed<Employee> {
  override readonly entity = () => Employee;
  override readonly records: SeedRecord<Employee>[] = [
    { data: { name: '田中太郎', age: 30, department: '開発部' } },
    { data: { name: '山田花子', age: 28, department: '営業部' } },
  ];
}

```
このスクリプトを実行すると、データベースに「社員データ」が自動で登録されます。今回は重複したとき用のチェックを入れていませんが追加も可能です。

### ♦マイグレーションとは
マイグレーションとは、「**データベースの構造を変更するための管理システム**」のことです。
新しいカラムを追加したり、テーブルを変更したりするときに使われます。
開発が進むにつれて、データベースの構造もどんどん変わることがありますが、その変更を安全に管理できるようにするのがマイグレーションの役割となります。
```:Migration
import { MigrationInterface, QueryRunner, TableColumn } from '********';

export class AddEmailToEmployee1699999999999 implements MigrationInterface {
    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.addColumn(
            'employee',
            new TableColumn({
                name: 'email',
                type: 'varchar',
                isNullable: true,
            })
        );
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.dropColumn('employee', 'email');
    }
}

```
#### ♥ マイグレーションの具体例
TypeORM を使えば、マイグレーションを作成してデータベースの構造を簡単に変更できます。
例えば、「社員テーブルに email カラムを追加する」マイグレーションを作成するしましょう。
以下のようなコードを書けば、データベースに変更を適用できます。
```:Migration
import { MigrationInterface, QueryRunner, TableColumn } from '*******';

export class AddEmailToEmployee1699999999999 implements MigrationInterface {
    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.addColumn(
            'employee',
            new TableColumn({
                name: 'email',
                type: 'varchar',
                isNullable: true,
            })
        );
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.dropColumn('employee', 'email');
    }
}
```
このマイグレーションを実行すれば、employee テーブルに email というカラムが追加されます。
そして、変更を元に戻したい場合（ロールバック）は down() メソッドを実行すれば良いでしょう。

## ♠まとめ
今回の内容を振り返ると、
- **エンティティ** → データベースのテーブルをプログラム上で扱いやすくするクラス
- **シード** → データベースの初期データを登録する仕組み
- **マイグレーション** → データベースの構造を安全に変更する仕組み

これらは開発作業の中で頻繁に使われるものですので、しっかり理解しておくと、今後のプロジェクトでも役立つかもしれませんね。

## ♠おまけ
一気にキャラを変えていくぜ！
今回の社会人が知っておいた方がいいビジネスマナーはこいつだ！
「**贈答するときは慎重に**」だぜ。
取引先にお祝いの品やお中元、お歳暮を贈るとき、先方に失礼のないようにしなくちゃいけないぜ。
企業にもよるが贈答品の受け渡し自体を禁止にしている場所もあるらしいからな。自分が良かれと思っても逆に相手に迷惑をかけたり不快な思いをさせてしまうこともあるんだぜ。

それを回避するためには、当たり前のことだが
**あらかじめ先方に確認しておくことが大事だぜ**

確認なしに送ってしまうと相手との関係が悪くなる可能性もあるからな。
気を付けるんだぜ。

これで今回は終わりだぜ。
**ターンエンド**