본문 바로가기

마이그레이션

번역일: 2026년 6월 20일

마이그레이션

소개

마이그레이션은 데이터베이스의 버전 관리 시스템이라고 생각하면 됩니다. 팀원이 소스 코드를 Pull 한 뒤 데이터베이스에 컬럼을 직접 추가해야 했던 경험이 있다면, 바로 그 문제를 마이그레이션이 해결해 줍니다.

Laravel의 Schema 파사드는 Laravel이 지원하는 모든 데이터베이스에서 테이블을 생성하고 조작할 수 있는 통일된 API를 제공합니다. 마이그레이션에서는 주로 이 파사드를 사용해 테이블과 컬럼을 생성하거나 변경합니다.

마이그레이션 생성

make:migration Artisan 명령어로 마이그레이션 파일을 생성할 수 있습니다. 생성된 파일은 database/migrations 디렉터리에 저장되며, 파일명에는 타임스탬프가 포함되어 실행 순서를 결정합니다.

php artisan make:migration create_flights_table

Laravel은 마이그레이션 이름에서 테이블 이름과 새 테이블 생성 여부를 자동으로 추론합니다. 이름에서 테이블명을 파악할 수 있으면 해당 테이블명을 미리 채워 넣은 마이그레이션 파일을 생성합니다. 추론이 어려운 경우에는 파일 안에서 직접 테이블명을 지정하면 됩니다.

생성될 마이그레이션 파일의 경로를 직접 지정하려면 --path 옵션을 사용하세요. 경로는 애플리케이션 루트를 기준으로 한 상대 경로입니다.

NOTE

마이그레이션 스텁(stub)은 스텁 퍼블리싱을 통해 커스터마이징할 수 있습니다.

마이그레이션 압축(Squashing)

애플리케이션을 개발하다 보면 마이그레이션 파일이 수백 개로 늘어날 수 있습니다. 이럴 때 schema:dump 명령어를 사용해 현재의 모든 마이그레이션을 하나의 SQL 파일로 압축할 수 있습니다.

php artisan schema:dump# 현재 데이터베이스 스키마를 덤프하고 기존 마이그레이션 파일을 모두 삭제php artisan schema:dump --prune

이 명령어를 실행하면 Laravel이 database/schema 디렉터리에 스키마 파일을 기록합니다. 파일명은 사용 중인 데이터베이스 연결에 따라 결정됩니다. 이후 마이그레이션을 실행할 때, 아직 실행된 마이그레이션이 없다면 Laravel은 먼저 이 스키마 파일의 SQL을 실행한 다음, 스키마 덤프에 포함되지 않은 나머지 마이그레이션을 순서대로 실행합니다.

테스트에서 로컬 개발 환경과 다른 데이터베이스 연결을 사용하는 경우, 해당 연결용 스키마 파일도 별도로 덤프해 두어야 합니다.

php artisan schema:dumpphp artisan schema:dump --database=testing --prune

스키마 파일은 소스 컨트롤에 커밋해 두면, 새로 합류한 팀원이 초기 데이터베이스 구조를 빠르게 구성할 수 있습니다.

WARNING

마이그레이션 압축은 MariaDB, MySQL, PostgreSQL, SQLite에서만 지원되며, 각 데이터베이스의 커맨드라인 클라이언트를 사용합니다.

마이그레이션 구조

마이그레이션 클래스는 updown 두 메서드를 포함합니다. up 메서드는 새 테이블, 컬럼, 인덱스를 추가할 때 사용하고, down 메서드는 up에서 수행한 작업을 되돌립니다.

두 메서드 모두 Laravel 스키마 빌더를 사용해 테이블을 자유롭게 생성하고 수정할 수 있습니다. 아래는 flights 테이블을 생성하는 마이그레이션 예시입니다.

<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * 마이그레이션 실행 */ public function up(): void { Schema::create('flights', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('airline'); $table->timestamps(); }); } /** * 마이그레이션 되돌리기 */ public function down(): void { Schema::drop('flights'); } };

마이그레이션 연결 지정

기본 데이터베이스 연결이 아닌 다른 연결을 사용해야 하는 마이그레이션이라면, $connection 프로퍼티를 설정하세요.

/** * 이 마이그레이션에서 사용할 데이터베이스 연결 * * @var string */ protected $connection = 'pgsql'; /** * 마이그레이션 실행 */ public function up(): void { // ... }

마이그레이션 건너뛰기

아직 활성화되지 않은 기능을 위한 마이그레이션처럼, 특정 조건에서만 실행해야 하는 마이그레이션이 있을 수 있습니다. 이 경우 shouldRun 메서드를 정의하고 false를 반환하면 해당 마이그레이션을 건너뜁니다.

use App\Models\Flight; use Laravel\Pennant\Feature; /** * 이 마이그레이션을 실행할지 결정 */ public function shouldRun(): bool { return Feature::active(Flight::class); }

마이그레이션 실행

아직 실행되지 않은 마이그레이션을 모두 실행하려면 migrate Artisan 명령어를 사용합니다.

php artisan migrate

어떤 마이그레이션이 이미 실행됐고 어떤 것이 대기 중인지 확인하려면 migrate:status 명령어를 사용하세요.

php artisan migrate:status

--step 옵션을 사용하면 각 마이그레이션이 개별 배치로 실행되어, 나중에 migrate:rollback으로 하나씩 되돌릴 수 있습니다.

php artisan migrate --step

실제로 실행하지 않고 어떤 SQL이 실행될지 미리 확인하려면 --pretend 플래그를 사용하세요.

php artisan migrate --pretend

마이그레이션 단독 실행 (격리)

여러 서버에 동시에 배포하면서 각 서버에서 마이그레이션이 실행될 경우, 두 서버가 동시에 마이그레이션을 실행하는 문제가 발생할 수 있습니다. 이를 방지하려면 --isolated 옵션을 사용하세요.

--isolated 옵션을 지정하면 Laravel이 마이그레이션 실행 전에 캐시 드라이버를 이용해 원자적 잠금(atomic lock)을 획득합니다. 잠금이 유지되는 동안 다른 서버에서 실행한 migrate 명령어는 아무 작업도 하지 않지만, 성공 종료 코드를 반환합니다.

php artisan migrate --isolated

WARNING

이 기능을 사용하려면 애플리케이션의 기본 캐시 드라이버가 memcached, redis, dynamodb, database, file, array 중 하나여야 하며, 모든 서버가 동일한 중앙 캐시 서버에 연결되어 있어야 합니다.

프로덕션 환경에서 강제 실행

일부 마이그레이션 작업은 데이터 손실을 유발할 수 있어, 프로덕션 데이터베이스에서 실행하면 확인 프롬프트가 표시됩니다. 확인 없이 강제 실행하려면 --force 플래그를 사용하세요.

php artisan migrate --force

마이그레이션 롤백

가장 최근에 실행한 마이그레이션 배치를 되돌리려면 migrate:rollback 명령어를 사용합니다. 하나의 배치에는 여러 마이그레이션 파일이 포함될 수 있습니다.

php artisan migrate:rollback

--step 옵션으로 롤백할 마이그레이션 수를 지정할 수 있습니다. 아래 예시는 최근 5개의 마이그레이션을 롤백합니다.

php artisan migrate:rollback --step=5

--batch 옵션으로 특정 배치 번호에 해당하는 마이그레이션만 롤백할 수도 있습니다. 배치 번호는 애플리케이션의 migrations 테이블에서 확인할 수 있습니다.

php artisan migrate:rollback --batch=3

실제 롤백 없이 실행될 SQL을 미리 확인하려면 --pretend 플래그를 사용하세요.

php artisan migrate:rollback --pretend

migrate:reset 명령어는 모든 마이그레이션을 한 번에 롤백합니다.

php artisan migrate:reset

롤백 후 재실행 (한 번에)

migrate:refresh 명령어는 모든 마이그레이션을 롤백한 뒤 다시 실행합니다. 데이터베이스 전체를 처음부터 다시 구성하는 효과가 있습니다.

php artisan migrate:refresh# 데이터베이스를 초기화하고 시더(seeder)까지 실행php artisan migrate:refresh --seed

--step 옵션으로 일부 마이그레이션만 롤백하고 재실행할 수 있습니다.

php artisan migrate:refresh --step=5

모든 테이블 삭제 후 마이그레이션

migrate:fresh 명령어는 데이터베이스의 모든 테이블을 삭제한 뒤 마이그레이션을 처음부터 실행합니다.

php artisan migrate:freshphp artisan migrate:fresh --seed

기본적으로는 기본 연결의 테이블만 삭제하지만, --database 옵션으로 대상 연결을 지정할 수 있습니다.

php artisan migrate:fresh --database=admin

WARNING

migrate:fresh 명령어는 테이블 접두사와 관계없이 모든 테이블을 삭제합니다. 다른 애플리케이션과 데이터베이스를 공유하는 환경에서는 특히 주의하세요.

테이블

테이블 생성

새 테이블을 생성하려면 Schema 파사드의 create 메서드를 사용합니다. 첫 번째 인수는 테이블 이름이고, 두 번째 인수는 Blueprint 객체를 받는 클로저입니다.

use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email'); $table->timestamps(); });

테이블을 생성할 때는 스키마 빌더의 다양한 컬럼 메서드를 사용해 컬럼을 정의할 수 있습니다.

테이블 / 컬럼 존재 여부 확인

hasTable, hasColumn, hasIndex 메서드로 테이블, 컬럼, 인덱스의 존재 여부를 확인할 수 있습니다.

if (Schema::hasTable('users')) { // "users" 테이블이 존재합니다. } if (Schema::hasColumn('users', 'email')) { // "users" 테이블에 "email" 컬럼이 존재합니다. } if (Schema::hasIndex('users', ['email'], 'unique')) { // "users" 테이블의 "email" 컬럼에 유니크 인덱스가 존재합니다. }

데이터베이스 연결 및 테이블 옵션

기본 연결이 아닌 다른 연결에서 스키마 작업을 하려면 connection 메서드를 사용하세요.

Schema::connection('sqlite')->create('users', function (Blueprint $table) { $table->id(); });

MariaDB 또는 MySQL을 사용할 때 스토리지 엔진, 문자 집합, 콜레이션을 지정할 수 있습니다.

Schema::create('users', function (Blueprint $table) { $table->engine('InnoDB'); // ... });
Schema::create('users', function (Blueprint $table) { $table->charset('utf8mb4'); $table->collation('utf8mb4_unicode_ci'); // ... });

temporary 메서드는 임시 테이블을 생성합니다. 임시 테이블은 현재 연결 세션에서만 보이며, 연결이 닫히면 자동으로 삭제됩니다.

Schema::create('calculations', function (Blueprint $table) { $table->temporary(); // ... });

테이블에 코멘트를 추가하려면 comment 메서드를 사용하세요. 이 기능은 MariaDB, MySQL, PostgreSQL에서만 지원됩니다.

Schema::create('calculations', function (Blueprint $table) { $table->comment('비즈니스 계산 테이블'); // ... });

테이블 수정

기존 테이블에 컬럼이나 인덱스를 추가하려면 Schema 파사드의 table 메서드를 사용합니다.

use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; Schema::table('users', function (Blueprint $table) { $table->integer('votes'); });

테이블 이름 변경 / 삭제

테이블 이름을 변경하려면 rename 메서드를 사용하세요.

use Illuminate\Support\Facades\Schema; Schema::rename($from, $to);

테이블을 삭제하려면 drop 또는 dropIfExists 메서드를 사용하세요.

Schema::drop('users'); Schema::dropIfExists('users');

외래 키가 있는 테이블 이름 변경 시 주의사항

외래 키가 있는 테이블의 이름을 변경하기 전에, 마이그레이션 파일에서 외래 키 제약 조건의 이름을 명시적으로 지정했는지 확인하세요. Laravel이 자동으로 생성한 이름을 그대로 사용하면, 제약 조건 이름이 기존 테이블 이름을 참조한 채로 남게 됩니다.

컬럼

컬럼 생성

기존 테이블에 컬럼을 추가하려면 Schema 파사드의 table 메서드를 사용합니다.

use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; Schema::table('users', function (Blueprint $table) { $table->integer('votes'); });

사용 가능한 컬럼 타입

스키마 빌더 Blueprint에는 다양한 컬럼 타입에 대응하는 메서드가 준비되어 있습니다.

불리언 타입

문자열 & 텍스트 타입

숫자 타입

날짜 & 시간 타입

바이너리 타입

오브젝트 & JSON 타입

UUID & ULID 타입

공간(Spatial) 타입

관계 타입

특수 타입

`bigIncrements()` {.collection-method .first-collection-method}

자동 증가하는 UNSIGNED BIGINT 컬럼(기본 키)을 생성합니다.

$table->bigIncrements('id');

`bigInteger()` {.collection-method}

BIGINT 컬럼을 생성합니다.

$table->bigInteger('votes');

`binary()` {.collection-method}

BLOB 컬럼을 생성합니다.

$table->binary('photo');

MySQL, MariaDB, SQL Server에서는 lengthfixed 인수를 사용해 VARBINARY 또는 BINARY 컬럼을 생성할 수 있습니다.

$table->binary('data', length: 16); // VARBINARY(16) $table->binary('data', length: 16, fixed: true); // BINARY(16)

`boolean()` {.collection-method}

BOOLEAN 컬럼을 생성합니다.

$table->boolean('confirmed');

`char()` {.collection-method}

지정한 길이의 CHAR 컬럼을 생성합니다.

$table->char('name', length: 100);

`dateTimeTz()` {.collection-method}

타임존 정보를 포함한 DATETIME 컬럼을 생성합니다. 선택적으로 소수점 이하 초 정밀도를 지정할 수 있습니다.

$table->dateTimeTz('created_at', precision: 0);

`dateTime()` {.collection-method}

DATETIME 컬럼을 생성합니다. 선택적으로 소수점 이하 초 정밀도를 지정할 수 있습니다.

$table->dateTime('created_at', precision: 0);

`date()` {.collection-method}

DATE 컬럼을 생성합니다.

$table->date('created_at');

`decimal()` {.collection-method}

전체 자릿수(total)와 소수점 자릿수(places)를 지정한 DECIMAL 컬럼을 생성합니다.

$table->decimal('amount', total: 8, places: 2);

`double()` {.collection-method}

DOUBLE 컬럼을 생성합니다.

$table->double('amount');

`enum()` {.collection-method}

이 문서는 Laravel 공식 문서(MIT)를 한국 개발자를 위해 번역·재구성한 것입니다.

번역일: 2026년 6월 20일