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

마이그레이션은 데이터베이스를 구조적이고 체계적인 방식으로 변경할 수 있는 편리한 방법입니다. SQL 조각을 직접 편집할 수도 있지만, 그럴 경우 다른 개발자들에게 해당 변경 사항을 실행해야 한다고 알려주어야 할 책임이 생깁니다. 또한 다음에 배포할 때 프로덕션 서버에 어떤 변경 사항을 적용해야 하는지도 추적해야 합니다.

데이터베이스 테이블 migrations는 이미 실행된 마이그레이션을 추적하므로, 마이그레이션 파일을 준비한 다음 spark migrate 명령을 실행하여 데이터베이스를 최신 상태로 만들기만 하면 됩니다. 또한 spark migrate --all을 사용하여 모든 네임스페이스의 마이그레이션을 포함할 수 있습니다.

마이그레이션 파일 이름

마이그레이션 파일 이름은 타임스탬프 접두사, 밑줄(_), 그리고 설명적인 이름(클래스명)으로 구성됩니다.

  • 2024-09-08-013653_AddBlogTable.php

각 마이그레이션은 생성 시점의 타임스탬프(2024-09-08-013653)를 사용하여 번호가 매겨지며, YYYY-MM-DD-HHIISS 형식을 따릅니다.

마이그레이션의 설명적 이름(AddBlogTable)은 PHP의 클래스명입니다. 따라서 유효한 클래스명으로 지정해야 합니다.

접두사의 연, 월, 일, 시간은 대시(-), 밑줄(_)로 구분하거나 구분 없이 사용할 수 있습니다. 예:

  • 2012-10-31-100538_AlterBlogTrackViews.php

  • 2012_10_31_100539_AlterBlogAddTranslations.php

  • 20121031100537_AddBlog.php

각 마이그레이션은 사용하는 메서드에 따라 숫자 순서대로 앞으로 또는 뒤로 실행됩니다. 이는 팀 환경에서 작업할 때 번호 충돌을 방지하는 데 도움이 됩니다.

마이그레이션 생성

이것은 블로그가 있는 새 사이트의 첫 번째 마이그레이션입니다. 모든 마이그레이션은 app/Database/Migrations/ 디렉터리에 위치하며 2022-01-31-013057_AddBlog.php와 같은 이름을 사용합니다.

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class AddBlog extends Migration
{
    public function up()
    {
        $this->forge->addField([
            'blog_id' => [
                'type'           => 'INT',
                'constraint'     => 5,
                'unsigned'       => true,
                'auto_increment' => true,
            ],
            'blog_title' => [
                'type'       => 'VARCHAR',
                'constraint' => '100',
            ],
            'blog_description' => [
                'type' => 'TEXT',
                'null' => true,
            ],
        ]);
        $this->forge->addKey('blog_id', true);
        $this->forge->createTable('blog');
    }

    public function down()
    {
        $this->forge->dropTable('blog');
    }
}

데이터베이스 연결과 데이터베이스 Forge 클래스는 각각 $this->db$this->forge를 통해 사용할 수 있습니다.

또는 커맨드라인 호출을 사용하여 마이그레이션 스켈레톤 파일을 생성할 수 있습니다. 자세한 내용은 커맨드라인 도구make:migration을 참조하세요.

참고

마이그레이션 클래스는 PHP 클래스이므로, 클래스명은 모든 마이그레이션 파일에서 고유해야 합니다.

외래 키

테이블에 외래 키가 포함되어 있으면 테이블이나 컬럼을 삭제하려 할 때 마이그레이션에서 문제가 발생할 수 있습니다. 마이그레이션 실행 중 외래 키 검사를 일시적으로 우회하려면 데이터베이스 연결에서 disableForeignKeyChecks()enableForeignKeyChecks() 메서드를 사용하세요.

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class AddBlog extends Migration
{
    public function up()
    {
        $this->db->disableForeignKeyChecks();

        // Migration rules would go here..

        $this->db->enableForeignKeyChecks();
    }
}

데이터베이스 그룹

마이그레이션은 단일 데이터베이스 그룹에 대해서만 실행됩니다. app/Config/Database.php에 여러 그룹이 정의된 경우, 기본적으로 동일한 설정 파일에 지정된 $defaultGroup에 대해 실행됩니다.

데이터베이스 그룹마다 다른 스키마가 필요한 경우도 있습니다. 예를 들어 하나의 데이터베이스는 일반적인 사이트 정보에 사용되고, 다른 데이터베이스는 중요한 데이터에 사용될 수 있습니다.

마이그레이션에서 $DBGroup 속성을 설정하여 올바른 그룹에 대해서만 마이그레이션이 실행되도록 할 수 있습니다. 이 이름은 데이터베이스 그룹 이름과 정확히 일치해야 합니다:

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class AddBlog extends Migration
{
    protected $DBGroup = 'alternate_db_group';

    public function up()
    {
        // ...
    }

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

참고

이미 실행된 마이그레이션을 추적하는 migrations 테이블은 항상 기본 데이터베이스 그룹에 생성됩니다.

네임스페이스

마이그레이션 라이브러리는 app/Config/Autoload.php에 정의하거나 Composer와 같은 외부 소스에서 로드한 모든 네임스페이스를 $psr4 속성을 사용하여 디렉터리 이름을 매칭하는 방식으로 자동으로 스캔합니다. Database/Migrations에서 찾은 모든 마이그레이션을 포함합니다.

각 네임스페이스는 자체 버전 순서를 가지며, 이를 통해 다른 네임스페이스에 영향을 주지 않고 각 모듈(네임스페이스)을 업그레이드 및 다운그레이드할 수 있습니다.

예를 들어, Autoload 설정 파일에 다음과 같은 네임스페이스가 정의되어 있다고 가정합니다:

$psr4 = [
    APP_NAMESPACE => APPPATH,
    'MyCompany'   => ROOTPATH . 'MyCompany',
];

이는 APPPATH/Database/MigrationsROOTPATH/MyCompany/Database/Migrations 양쪽에 위치한 마이그레이션을 탐색합니다. 이를 통해 재사용 가능한 모듈식 코드 패키지에 마이그레이션을 간편하게 포함시킬 수 있습니다.

커맨드라인 도구

CodeIgniter는 커맨드라인에서 마이그레이션 작업을 돕기 위한 여러 명령어를 제공합니다. 이 도구들은 사용하고자 하는 분들에게 편의를 제공합니다. 주로 MigrationRunner 클래스 내에서 사용 가능한 동일한 메서드에 대한 접근을 제공합니다.

migrate

사용 가능한 모든 마이그레이션으로 데이터베이스 그룹을 마이그레이션합니다:

php spark migrate

migrate는 다음 옵션과 함께 사용할 수 있습니다:

  • -g - 데이터베이스 그룹을 지정합니다. 지정된 경우 해당 데이터베이스 그룹의 마이그레이션만 실행됩니다. 지정하지 않으면 모든 마이그레이션이 실행됩니다.

  • -n - 네임스페이스를 선택합니다. 지정하지 않으면 App 네임스페이스가 사용됩니다.

  • --all - 모든 네임스페이스를 최신 마이그레이션으로 마이그레이션합니다.

이 예제는 test 데이터베이스 그룹에서 Acme\Blog 네임스페이스의 새 마이그레이션을 실행합니다:

Unix의 경우:

php spark migrate -g test -n Acme\\Blog

Windows의 경우:

php spark migrate -g test -n Acme\Blog

--all 옵션을 사용하면 아직 실행되지 않은 마이그레이션을 찾기 위해 모든 네임스페이스를 스캔합니다. 이것들은 모두 수집된 후 생성 날짜별로 그룹으로 정렬됩니다. 이는 메인 애플리케이션과 모든 모듈 간의 잠재적 충돌을 최소화하는 데 도움이 됩니다.

migrate:rollback

모든 마이그레이션을 초기 상태(마이그레이션 0)로 롤백합니다:

php spark migrate:rollback

migrate:rollback은 다음 옵션과 함께 사용할 수 있습니다:

  • -b - 배치를 선택합니다: 자연수로 배치를 지정합니다.

  • -f - 확인 질문을 강제로 건너뜁니다. 이 질문은 프로덕션 환경에서만 표시됩니다.

migrate:refresh

먼저 모든 마이그레이션을 롤백한 다음 전체 마이그레이션을 실행하여 데이터베이스 상태를 새로 고칩니다:

php spark migrate:refresh

migrate:refresh는 다음 옵션과 함께 사용할 수 있습니다:

  • -g - 데이터베이스 그룹을 지정합니다. 지정된 경우 해당 데이터베이스 그룹의 마이그레이션만 실행됩니다. 지정하지 않으면 모든 마이그레이션이 실행됩니다.

  • -n - 네임스페이스를 선택합니다. 지정하지 않으면 App 네임스페이스가 사용됩니다.

  • --all - 모든 네임스페이스를 새로 고칩니다.

  • -f - 확인 질문을 강제로 건너뜁니다. 이 질문은 프로덕션 환경에서만 표시됩니다.

migrate:status

모든 마이그레이션 목록과 실행 날짜 및 시간을 표시하거나, 실행되지 않은 경우 ‘–‘를 표시합니다:

php spark migrate:status

...

+----------------------+-------------------+-----------------------+---------+---------------------+-------+
| Namespace            | Version           | Filename              | Group   | Migrated On         | Batch |
+----------------------+-------------------+-----------------------+---------+---------------------+-------+
| App                  | 2022-04-06-234508 | CreateCiSessionsTable | default | 2022-04-06 18:45:14 | 2     |
| CodeIgniter\Settings | 2021-07-04-041948 | CreateSettingsTable   | default | 2022-04-06 01:23:08 | 1     |
| CodeIgniter\Settings | 2021-11-14-143905 | AddContextColumn      | default | 2022-04-06 01:23:08 | 1     |
+----------------------+-------------------+-----------------------+---------+---------------------+-------+

migrate:status는 다음 옵션과 함께 사용할 수 있습니다:

  • -g - 데이터베이스 그룹을 지정합니다. 지정된 경우 해당 데이터베이스 그룹의 마이그레이션만 확인됩니다. 지정하지 않으면 모든 마이그레이션이 확인됩니다.

make:migration

app/Database/Migrations에 마이그레이션 스켈레톤 파일을 생성합니다. 현재 타임스탬프를 자동으로 앞에 붙입니다. 생성되는 클래스명은 파일명의 파스칼 케이스 버전입니다.

php spark make:migration <class> [options]

make:migration은 다음 옵션과 함께 사용할 수 있습니다:

  • --namespace - 루트 네임스페이스를 설정합니다. 기본값: APP_NAMESPACE.

  • --suffix - 클래스명에 컴포넌트 제목을 추가합니다.

데이터베이스 세션을 위한 마이그레이션 파일을 생성하는 데 사용할 수 있는 추가 옵션도 있습니다:

  • --session - 데이터베이스 세션용 마이그레이션 파일을 생성합니다.

  • --table - 데이터베이스 세션에 사용할 테이블 이름입니다. 기본값: ci_sessions.

  • --dbgroup - 데이터베이스 세션에 사용할 데이터베이스 그룹입니다. 기본값: default.

마이그레이션 환경설정

다음은 app/Config/Migrations.php에서 사용할 수 있는 마이그레이션의 모든 설정 옵션 테이블입니다.

설정 항목

기본값

옵션

설명

enabled

true

true / false

마이그레이션을 활성화하거나 비활성화합니다.

table

migrations

없음

스키마 버전 번호를 저장하는 테이블 이름입니다. 이 테이블은 항상 기본 데이터베이스 그룹($defaultGroup)에 생성됩니다.

timestampFormat

Y-m-d-His_

마이그레이션 생성 시 타임스탬프에 사용할 형식입니다.

lock

false

true / false

멀티 프로세스 환경(예: Kubernetes)에서 동시 마이그레이션을 방지하기 위한 분산 잠금을 활성화합니다.

클래스 레퍼런스

class CodeIgniter\Database\MigrationRunner
findMigrations()
반환:

마이그레이션 파일 배열

반환 형식:

array

path 속성에서 찾은 마이그레이션 파일명 배열이 반환됩니다.

latest($group)
매개변수:
  • $group (mixed) – 데이터베이스 그룹 이름. null이면 기본 데이터베이스 그룹이 사용됩니다.

반환:

성공 시 true, 실패 시 false

반환 형식:

bool

네임스페이스(또는 모든 네임스페이스)에 대한 마이그레이션을 찾고, 아직 실행되지 않은 마이그레이션을 파악한 후, 버전 순서대로(네임스페이스가 혼합된 형태로) 실행합니다.

regress($targetBatch, $group)
매개변수:
  • $targetBatch (int) – 다운그레이드할 이전 배치; 1 이상은 배치를 지정하고, 0은 전체 롤백, 음수는 상대적 배치를 의미합니다 (예: -3은 “3 배치 이전”을 의미)

  • $group (?string) – 데이터베이스 그룹 이름. null이면 기본 데이터베이스 그룹이 사용됩니다.

반환:

성공 시 true, 실패 또는 마이그레이션을 찾을 수 없는 경우 false

반환 형식:

bool

Regress는 변경 사항을 배치 단위로 이전 상태로 롤백하는 데 사용할 수 있습니다.

<?php

$migration->regress(5);
$migration->regress(-1);
force($path, $namespace, $group)
매개변수:
  • $path (mixed) – 유효한 마이그레이션 파일의 경로.

  • $namespace (mixed) – 제공된 마이그레이션의 네임스페이스.

  • $group (mixed) – 데이터베이스 그룹 이름. null이면 기본 데이터베이스 그룹이 사용됩니다.

반환:

성공 시 true, 실패 시 false

반환 형식:

bool

순서나 배치에 관계없이 단일 파일을 강제로 마이그레이션합니다. up() 또는 down() 메서드는 이미 마이그레이션되었는지 여부에 따라 자동으로 감지됩니다.

참고

이 메서드는 테스트 용도로만 권장되며 데이터 일관성 문제를 일으킬 수 있습니다.

setNamespace($namespace)
매개변수:
  • $namespace (string|null) – 애플리케이션 네임스페이스. null이면 모든 네임스페이스를 대상으로 합니다.

반환:

현재 MigrationRunner 인스턴스

반환 형식:

CodeIgniter\Database\MigrationRunner

라이브러리가 마이그레이션 파일을 탐색할 네임스페이스를 설정합니다:

<?php

$migration->setNamespace($namespace)->latest();

참고

null로 설정하면 모든 네임스페이스에서 마이그레이션 파일을 탐색합니다.

setGroup($group)
매개변수:
  • $group (string) – 데이터베이스 그룹 이름.

반환:

현재 MigrationRunner 인스턴스

반환 형식:

CodeIgniter\Database\MigrationRunner

라이브러리가 마이그레이션 파일을 탐색할 그룹을 설정합니다:

<?php

$migration->setGroup($group)->latest();