코드이그나이터4 데이터베이스 다루기 - 4 - 마이그레이션

koeunyeon·2021년 3월 30일
1

마이그레이션

이번 챕터의 코드는 https://github.com/koeunyeon/ci4/tree/model-migration 에 있습니다.

마이그레이션이란?

최근에 나온 대부분의 웹 프레임워크는 "마이그레이션"을 사용합니다. 간단하게 말하면, 자동으로 "데이터베이스의 버전 관리"를 하는 겁니다.
많은 서비스에서 프로그램과 데이터베이스는 끊임없이 변화해 나갑니다. 이 중 프로그램은 형상 관리(VCS - Version Control System)을 통해 소스코드의 변화를 추적해 나가지만, 데이터베이스는 그렇지 못한 경우가 많았습니다. 기껏해야 SQL 스크립트를 버전관리에 추가하는 정도였죠.
마이그레이션은 이 과정을 자동화합니다. 코드이그나이터4의 경우를 예로 들면 PHP로 데이터베이스 테이블 스키마를 정의한 파일을 생성하고 이 파일을 통해 테이블을 생성하거나 수정하거나 삭제하게 됩니다. 이 때 사용한 파일을 마이그레이션 파일이라고 부르는데, 마이그레이션 파일은 여러 개가 생성될 수 있어서 선택적 데이터베이스 관리가 가능해집니다.

마이그레이션 파일 만들기

직접 마이그레이션을 만들고, 마이그레이션을 통해 데이터베이스 테이블을 관리해 보겠습니다.
이번에는 PHPStorm이 아니라, 직접 터미널에서 입력하겠습니다. 마이그레이션은 개인의 로컬 서버 뿐만 아니라 개발 서버, 운영 서버에도 동일하게 해야 하는 경우가 많으므로 터미널로 사용하는 것이 빠르기 때문입니다.
마이그레이션은 컨트롤러에서도 불러서 사용할 수 있지만, DDL(Data Definition Language - create table, alter table .. 등)을 직접 웹에서 호출하는 것은 위험천만하기 짝이 없으므로 가능하면 사용하지 마세요.

우선 터미널을 엽니다. 윈도우즈에서는 Windows 키를 누르고 cmd를 입력하면 됩니다.

이제 프로젝트 루트 디렉토리로 이동합니다.

D:
cd D:\ci4\sample

마이그레이션 파일을 생성합니다.

php spark migrate:create rich

위 명령어 중 rich는 그냥 이름이므로 식별하기 좋은 이름으로 적어주세요. 지금은 sample_rich 테이블을 만들 예정이어서 rich로 지었습니다.

PHPStorm으로 돌아와서 app/Database/Migrations 디렉토리 아래에 보면 Y-m-d-u_이름.php 파일이 생성되어 있습니다. 예를 들면 2021-02-02-035600_rich.php 처럼이요.

내용을 살펴보면 아래와 같은 파일이 생성되어 있습니다.

<?php namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class Rich extends Migration
{
   public function up() // (1)
   {
      //
   }

   //--------------------------------------------------------------------

   public function down() // (2)
   {
      //
   }
}

(1) 마이그레이션이 실행될 때 사용하는 메소드입니다.
(2) 마이그레이션을 롤백(rollback - 되돌림) 하거나, 리프레시(refresh - 삭제하고 다시 생성)할 때 사용하는 메소드입니다.

마이그레이션 정의하기

생성된 마이그레이션 파일 내용을 아래와 같이 변경하겠습니다.

<?php namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class Rich extends Migration
{
 public function up()
 {
        // (1)
        $this->forge->addField([
            'sample_rich_id'          => [ // (2)
                'type'           => 'BIGINT', // (3)
                'unsigned'       => true, // (4)
                'auto_increment' => true, // (5)
            ],
            'name'       => [
                'type'       => 'VARCHAR',
                'constraint' => '40', // (6)
            ],
            'age' => [
                'type' => 'INT',
                'null' => true, // (7)
            ],
            'created_at' => [  // (8)
                'type'       => 'VARCHAR',
                'constraint' => '25',  // (9)
            ],
            'updated_at' => [  // (10)
                'type'       => 'VARCHAR',
                'constraint' => '25',
            ],
            'deleted_at' => [  // (11)
                'type'       => 'VARCHAR',
                'constraint' => '25',
                'null' => true,
            ]
        ]);

        $this->forge->addKey('sample_rich_id', true); // (12)
        $this->forge->createTable('sample_rich'); // (13)
 }

 //--------------------------------------------------------------------

 public function down()
 {
        $this->forge->dropTable('sample_rich'); // (14)
 }
}

(1) 데이터베이스 필드를 정의합니다. forge는 데이터베이스 관리 클래스라고 생각하시면 됩니다. addField 메소드는 연관배열을 파라미터로 받는데, 연관배열의 각 키가 열 이름이 됩니다.

(2) 연관배열의 키가 sample_rich_id이므로 sample_rich_id라는 열을 정의한다는 의미가 됩니다.

(3) type은 "데이터베이스의 타입"입니다. PHP의 타입이 아니므로 주의하세요.

(4) unsigned 는 짐작할 수 있듯이 "자연수"를 나타냅니다. 즉 음수가 들어갈 수 없습니다.

(5) auto_increment는 자동 증가를 의미합니다.

(6) constraint 속성은 데이터의 길이를 나타냅니다. VARCHAR의 경우 데이터의 길이는 필수이므로 40으로 지정했습니다.

(7) null => true라면 allow null, 즉 null 허용입니다. 기본값은 false입니다.

(8) created_at은 생성 시간을 나타냅니다. 코드이그나이터4에서는 모델에서 자동으로 생성, 수정, 삭제 시간을 넣어주는 기능이 있습니다. 이 기능을 사용해 보기 위해 created_at 열을 추가합니다.

(9) created_at 속성은 기본적으로 PHP의 datetime 형식을 따릅니다. 2021-02-01 22:32:23 처럼요. 19글자를 차지하지만 혹시 모를 여백을 위해 25글자로 맞춰둡니다.

(10) updated_at 열은 수정 시간을 나타냅니다. 데이터가 수정되면 자동으로 updated_at 열도 업데이트됩니다.

(11) deleted_at 열은 삭제 시간을 나타냅니다. 코드이그나이터4에서 소프트 딜리트(soft delete)를 사용할 경우 데이터를 실제로 삭제하는 것이 아니라 "삭제되었다고 표시"만 할 수 있습니다. 이 때 "삭제되었다고 표시"하는 기준이 deleted_at이 비어있는 지 확인하는 것이기 때문에 deleted_at 열을 정의합니다.

(12) addKey 메소드로 주 키 (primary key)를 설정합니다.
첫번째 파라미터는 열의 이름, 두번째 파라미터는 주 키인지 여부입니다. 두번째 파라미터가 false라면 데이터베이스에 단순 인덱스만 추가하게 됩니다.
샘플에는 나와있지 않지만 세번째 파라미터가 true라면 유일 인덱스(Unique Index)로 추가하게 됩니다. 세번째 파라미터의 기본값은 false입니다.

(13) 테이블을 생성합니다. 파라미터는 테이블의 이름입니다. 예제에서는 sample_rich 테이블을 생성했습니다.

(14) 테이블을 삭제하기 위해서는 $this->forge->dropTable(테이블이름); 형태로 사용합니다.

마이그레이션 실행하기

마이그레이션 파일을 실제 데이터베이스에 적용하려면 터미널에서 아래와 같이 입력합니다.

php spark migrate

아래와 같은 메세지가 나오면 성공입니다.

Running all new migrations...
Done

실제로 잘 적용되었는지 확인해 봅시다. PHPStorm에서 Database - Schemas - ci4db 를 클릭하고 ctrl + F5키를 눌러 새로고침하면 sample_rich 테이블이 있는 것을 확인할 수 있습니다.

sample_rich 테이블 선택 후 ctrl + B키를 눌러 테이블 스키마를 확인해 보면 아래와 같습니다.

-- auto-generated definition
create table sample_rich
(
    sample_rich_id bigint unsigned auto_increment
        primary key,
    name           varchar(40) not null,
    age            int         null,
    created_at     varchar(25) not null,
    updated_at     varchar(25) not null,
    deleted_at     varchar(25) null
)
    charset = utf8;

터미널에서 현재 마이그레이션 상태를 확인해 보겠습니다. 현재 마이그레이션 파일들 목록이 나옵니다.

php spark migrate:status

만약 마이그레이션을 되돌리려면 롤백(rollback)을 사용할 수 있습니다. 아래 내용을 터미널에 입력하면 마이그레이션 파일의 down()메소드가 실행되어 테이블이 삭제(drop)됩니다.

php spark migrate:rollback

테이블을 지우고 다시 만드는 것을 한번에 할 수도 있습니다. 테스트 데이터를 깨끗하게 하고 싶을 때 주로 사용하게 됩니다.

php spark migrate:refresh
profile
스타트업에 관심이 많은 10 + n년차 웹 개발자. 자바 스프링 (혹은 부트), 파이썬 플라스크, PHP를 주로 다룹니다.

0개의 댓글