Home 라라벨로 배우는 php 웹 프로그래밍
Post
Cancel

라라벨로 배우는 php 웹 프로그래밍

라라벨로 배우는 실전 PHP 웹 프로그래밍

PART 1 라라벨 입문

7. 데이터베이스 마이그레이션

데이터베이스 마이그레이션이란, 테이블 스키마의 버전 관리다. 데이터베이스 마이그레이션을 이용하면, 테이블에 새로운 열을 추가한다든지, 열 이름을 바꾼다든지 하는 이력을 마이그레이션 코드로 남겨 두고 필요할 때마다 마이그레이션을 실행했다가 롤백하는 등의 작업을 자유롭게 할 수 있다.

SQL 문장을 이용해서 데이터베이스 스키라를 만들고 관리할 수 있는데, 마이그레이션은 왜 필요할까?

  • 모던 개발 방법론
    팀 내 개발자들은 같은 데이터베이스 스키마로 개발해야 한다. 한 개발자의 스키마 변경을 다른 개발자도 사용해야 한다. 개발 환경뿐 아니라 테스트 서버, 지속적 통합 서버, 운영 서버 등에서 환경을 쉽고 빠르게 만들 수 있는 도구가 필요하다.

  • ‘완벽’이란 없다. ‘완벽 추구’만 있을 뿐이다.
    비지니스는 계속 변하고, 요구 사항도 계속 변한다. 데이터베이스 모델링을 기가 막히게 했더라도 시간이 지나면 바뀔 수 밖에 없다(users 테이블에 직원과 고객을 모두 넣었는데, 직원이 고객이 되면? 또는 직원일 때의 이메일과 고객일 때의 이메일이 다르다면?) 또는 실수로 열이름에 오탈자가 들어갔다거나, 모델링을 잘못했는데 빠르게 롤백해야 하는 상황도 생각해 볼 수 있다.

번거롭더라도 데이터베이스 마이그레이션을 작성해 두면 데이터베이스 스키마 때문에 위기에 처하거나 변경 요구가 생겼을 때 효과적으로 대응할 수 있다.


7.1 마이그레이션 만들기

이전 테이블을 모두 삭제한다

데이터베이스 정리

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ mysql -uhomestead -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 8.0.22 Homebrew

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use myapp;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> set foreign_key_checks=0;
Query OK, 0 rows affected (0.00 sec)

mysql> drop table posts;
Query OK, 0 rows affected (0.01 sec)

mysql> drop table authors;
Query OK, 0 rows affected (0.01 sec)

mysql> set foreign_key_checks=1;
Query OK, 0 rows affected (0.00 sec)

새로운 마이그레이션 만든다. --create=테이블_이름--table=테이블_이름 옵션을 주면 좀더 많은 코드를 생성해 준다.

마이그레이션 클래스 뼈대 코드 만들기

1
2
3
4
$ php artisan make:migration create_posts_table --create=posts 
Created Migration: 2021_01_17_141752_create_posts_table
$ php artisan make:migration create_authors_table --create=authors
Created Migration: 2021_01_17_141834_create_authors_table

생성된 파일은 database/migrations 디렉터리 아래에 있다.

NOTE

1
2
마이그레이션의 파일 이름  
테이블과 모델 이름의 관례처럼 마이그레이션 이름 명명에 엄격한 규칙이 있는 것은 아니다. 관례적으로 스네이크 표기법을 사용하며, create_, make_, add_, drop_, change_ 등으로 시작하고, _table로 끝난다. 둘 사이에는 아미그레이션을 설명할 수 있는 내용을 기술한다.

up() 은 마이그레이션을 실행하는 메서드이고, down() 은 롤백을 위한 메서드다.

database/migrations/2021_01_17_141752_create_posts_table.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('body');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

database/migrations/2021_01_17_141834_create_authors_table.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateAuthorsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('authors', function (Blueprint $table) {
            $table->increments('id');
            $table->string('email',255);
            $table->string('password',60);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('authors');
    }
}
  • Schema::create(string $table , \Closure $callback) 테이블을 만든다.
  • Schema::dropIfExists(string $table ) 테이블을 지운다.
  • Schema::table(string $table , \Closure $callback) 테이블을 생성/삭제를 제외한 나머지 대부분의 스키마 관련 작업을 담는다.
메서드내용
boolean(), dateTime(), enum(), integer(), timestamp()열 타입 메서드
timestamps(), softDeletes()도우미 메서드
nullable(), default(), unsigned()장식 메서드
unique(), index()인덱스 메서드

전체 목록은 공식 문서를 참고 하자.

note

1
2
타입 힌트
마이그레이션 코드에서 blueprint라 타이핑된 문자열은 타입 힌트다. Schema::create() 메서드의 주 번째 인자는 콜백 함수인데, 콜백 함수가 인자로 받는 $table이 Illuminate/Database/Schema/Blueprint 클래스의 인스턴스여야 한다고 강제하는 것이다.

7.2 마이그레이션 실행

마이그레이션 실행 확인

마이그레시연 힐생

1
2
3
4
5
6
7
8
9
$ php artisan migrate  
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (16.35ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (9.62ms)
Migrating: 2021_01_17_141752_create_posts_table
Migrated:  2021_01_17_141752_create_posts_table (4.58ms)
Migrating: 2021_01_17_141834_create_authors_table
Migrated:  2021_01_17_141834_create_authors_table (4.69ms)

마이그레이션 실행 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
$ mysql -uhomestead -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 39
Server version: 8.0.22 Homebrew

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use myapp;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> describe posts;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int unsigned | NO   | PRI | NULL    | auto_increment |
| title      | varchar(255) | NO   |     | NULL    |                |
| body       | text         | NO   |     | NULL    |                |
| created_at | timestamp    | YES  |     | NULL    |                |
| updated_at | timestamp    | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

mysql> describe authors;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int unsigned | NO   | PRI | NULL    | auto_increment |
| email      | varchar(255) | NO   |     | NULL    |                |
| password   | varchar(60)  | NO   |     | NULL    |                |
| created_at | timestamp    | YES  |     | NULL    |                |
| updated_at | timestamp    | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

7.3 롤백

롤백

1
2
3
4
5
6
7
8
9
$ php artisan migrate:rollback
Rolling back: 2021_01_17_141834_create_authors_table
Rolled back:  2021_01_17_141834_create_authors_table (13.51ms)
Rolling back: 2021_01_17_141752_create_posts_table
Rolled back:  2021_01_17_141752_create_posts_table (3.25ms)
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back:  2014_10_12_100000_create_password_resets_table (4.22ms)
Rolling back: 2014_10_12_000000_create_users_table
Rolled back:  2014_10_12_000000_create_users_table (3.21ms)

테이블이 삭제 되었다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ mysql -uhomestead -p        
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 41
Server version: 8.0.22 Homebrew

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use myapp;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> describe posts;
ERROR 1146 (42S02): Table 'myapp.posts' doesn't exist
mysql> describe authors;
ERROR 1146 (42S02): Table 'myapp.authors' doesn't exist

migration 테이블은 롤백 해도 지워지지 않는다.

마이그레이션 실행

1
2
3
4
5
6
7
8
9
$ php artisan migrate  
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (16.35ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (9.62ms)
Migrating: 2021_01_17_141752_create_posts_table
Migrated:  2021_01_17_141752_create_posts_table (4.58ms)
Migrating: 2021_01_17_141834_create_authors_table
Migrated:  2021_01_17_141834_create_authors_table (4.69ms)

7.4 열 추가

authors 테이블에 name 컬럼을 추가 해 보자.

테이블 열 추가 마이드레이션 뼈대 코드 만들기

1
2
$ php artisan make:migration add_name_to_authors_table --table=authors
Created Migration: 2021_01_17_145632_add_name_to_authors_table

database/migrations/2021_01_17_145632_add_name_to_authors_table.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddNameToAuthorsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('authors', function (Blueprint $table) {
            $table->string('name')->nullable();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('authors', function (Blueprint $table) {
            $table->dropColumn('name');
        });
    }
}

create() 메소드가 아닌 table() 메서드를 사용한다

마이그레이션 실행

1
2
3
$ php artisan migrate
Migrating: 2021_01_17_145632_add_name_to_authors_table
Migrated:  2021_01_17_145632_add_name_to_authors_table (2.69ms)

마이그레이션 실행 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ mysql -uhomestead -p        
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 53
Server version: 8.0.22 Homebrew

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use myapp;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> describe authors;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int unsigned | NO   | PRI | NULL    | auto_increment |
| email      | varchar(255) | NO   |     | NULL    |                |
| password   | varchar(60)  | NO   |     | NULL    |                |
| created_at | timestamp    | YES  |     | NULL    |                |
| updated_at | timestamp    | YES  |     | NULL    |                |
| name       | varchar(255) | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

초기화 및 새로고침

migrate:rollback 명령은 직전 마이그레이션만 록백 하는 반면, migrate:reset 명령은 모든 마이그레이션을 롤백하고 데이터베이스를 초기화한다. migrateLrefresh는 초기화한 후, 마이그레이션을 다시 실행하는 명령이다.

마이그레이션 새로고침

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
% php artisan migrate:refresh
Rolling back: 2021_01_17_145632_add_name_to_authors_table
Rolled back:  2021_01_17_145632_add_name_to_authors_table (13.63ms)
Rolling back: 2021_01_17_141834_create_authors_table
Rolled back:  2021_01_17_141834_create_authors_table (2.90ms)
Rolling back: 2021_01_17_141752_create_posts_table
Rolled back:  2021_01_17_141752_create_posts_table (2.90ms)
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back:  2014_10_12_100000_create_password_resets_table (3.84ms)
Rolling back: 2014_10_12_000000_create_users_table
Rolled back:  2014_10_12_000000_create_users_table (3.18ms)
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (10.88ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (12.00ms)
Migrating: 2021_01_17_141752_create_posts_table
Migrated:  2021_01_17_141752_create_posts_table (5.69ms)
Migrating: 2021_01_17_141834_create_authors_table
Migrated:  2021_01_17_141834_create_authors_table (4.86ms)
Migrating: 2021_01_17_145632_add_name_to_authors_table
Migrated:  2021_01_17_145632_add_name_to_authors_table (5.58ms)
This post is licensed under CC BY 4.0 by the author.

자바스터디 9주차

자바스터디 10주차

Comments powered by Disqus.

Trending Tags