본문으로 건너뛰기
버전: 13.x

데이터베이스: 마이그레이션 (Database: Migrations)

소개 (Introduction)

마이그레이션은 데이터베이스의 버전 관리 시스템과 같은 역할을 하여, 팀이 애플리케이션의 데이터베이스 스키마를 정의하고 공유할 수 있게 해줍니다. 소스 컨트롤에서 변경 사항을 풀한 후 팀원에게 로컬 데이터베이스 스키마에 컬럼을 수동으로 추가하라고 알려야 했던 경험이 있다면, 바로 그 문제를 마이그레이션이 해결해 줍니다.

Laravel Schema 파사드는 Laravel이 지원하는 모든 데이터베이스 시스템에서 테이블을 생성하고 조작할 수 있는 데이터베이스 독립적인 기능을 제공합니다. 일반적으로 마이그레이션은 이 파사드를 사용하여 데이터베이스 테이블과 컬럼을 생성하고 수정합니다.

마이그레이션 생성하기 (Generating Migrations)

make:migration Artisan 명령어를 사용하여 데이터베이스 마이그레이션을 생성할 수 있습니다. 새로운 마이그레이션은 database/migrations 디렉터리에 배치됩니다. 각 마이그레이션 파일 이름에는 Laravel이 마이그레이션의 순서를 결정할 수 있도록 하는 타임스탬프가 포함되어 있습니다.

php artisan make:migration create_flights_table

Laravel은 마이그레이션의 이름을 사용하여 테이블 이름과 새 테이블 생성 여부를 추측합니다. Laravel이 마이그레이션 이름에서 테이블 이름을 확인할 수 있는 경우, 생성된 마이그레이션 파일에 지정된 테이블 정보가 자동으로 채워집니다. 그렇지 않으면 마이그레이션 파일에서 테이블을 직접 지정하면 됩니다.

생성된 마이그레이션의 경로를 사용자 지정하려면 make:migration 명령어 실행 시 --path 옵션을 사용할 수 있습니다. 지정된 경로는 애플리케이션의 기본 경로에 상대적이어야 합니다.

[!NOTE] 마이그레이션 스텁은 스텁 퍼블리싱을 사용하여 사용자 지정할 수 있습니다.

마이그레이션 스쿼시

애플리케이션을 개발하다 보면 시간이 지남에 따라 점점 더 많은 마이그레이션이 쌓일 수 있습니다. 이로 인해 database/migrations 디렉터리에 수백 개의 마이그레이션 파일이 생길 수 있습니다. 원한다면 마이그레이션을 단일 SQL 파일로 "스쿼시"할 수 있습니다. 시작하려면 schema:dump 명령어를 실행하세요.

php artisan schema:dump

# Dump the current database schema and prune all existing migrations...
php artisan schema:dump --prune

이 명령어를 실행하면 Laravel은 애플리케이션의 database/schema 디렉터리에 "스키마" 파일을 생성합니다. 스키마 파일의 이름은 데이터베이스 연결에 해당합니다. 이후 데이터베이스 마이그레이션을 시도할 때 다른 마이그레이션이 아직 실행되지 않았다면, Laravel은 먼저 사용 중인 데이터베이스 연결의 스키마 파일에 있는 SQL 구문을 실행합니다. 스키마 파일의 SQL 구문을 실행한 후에는 스키마 덤프에 포함되지 않은 나머지 마이그레이션을 실행합니다.

애플리케이션의 테스트에서 로컬 개발 시 일반적으로 사용하는 것과 다른 데이터베이스 연결을 사용하는 경우, 테스트에서 데이터베이스를 구축할 수 있도록 해당 데이터베이스 연결을 사용해 스키마 파일을 덤프해야 합니다. 로컬 개발 시 일반적으로 사용하는 데이터베이스 연결을 덤프한 후 이 작업을 수행할 수 있습니다.

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

팀의 다른 새로운 개발자가 애플리케이션의 초기 데이터베이스 구조를 빠르게 생성할 수 있도록 데이터베이스 스키마 파일을 소스 컨트롤에 커밋해야 합니다.

[!WARNING] 마이그레이션 스쿼시는 MariaDB, MySQL, PostgreSQL 및 SQLite 데이터베이스에만 사용할 수 있으며, 데이터베이스의 커맨드라인 클라이언트를 활용합니다.

마이그레이션 구조 (Migration Structure)

마이그레이션 클래스에는 updown 두 가지 메서드가 포함되어 있습니다. up 메서드는 데이터베이스에 새 테이블, 컬럼 또는 인덱스를 추가하는 데 사용되고, down 메서드는 up 메서드에서 수행된 작업을 되돌려야 합니다.

두 메서드 모두에서 Laravel 스키마 빌더를 사용하여 테이블을 명시적으로 생성하고 수정할 수 있습니다. Schema 빌더에서 사용할 수 있는 모든 메서드에 대해 알아보려면 해당 문서를 확인하세요. 예를 들어, 다음 마이그레이션은 flights 테이블을 생성합니다.

<?php

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

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('flights', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('airline');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::drop('flights');
}
};

마이그레이션 연결 설정

마이그레이션이 애플리케이션의 기본 데이터베이스 연결이 아닌 데이터베이스 연결과 상호 작용하는 경우 마이그레이션의 $connection 속성을 설정해야 합니다.

/**
* The database connection that should be used by the migration.
*
* @var string
*/
protected $connection = 'pgsql';

/**
* Run the migrations.
*/
public function up(): void
{
// ...
}

마이그레이션 건너뛰기

때로는 마이그레이션이 아직 활성화되지 않은 기능을 지원하고 아직 실행되기를 원하지 않을 수도 있습니다. 이 경우 마이그레이션에 shouldRun 메서드를 정의할 수 있습니다. shouldRun 메서드가 false를 반환하는 경우 마이그레이션은 건너뜁니다.

use App\Models\Flight;
use Laravel\Pennant\Feature;

/**
* Determine if this migration should run.
*/
public function shouldRun(): bool
{
return Feature::active(Flight::class);
}

마이그레이션 실행 (Running Migrations)

미해결 마이그레이션을 모두 실행하려면 migrate Artisan 명령을 실행하세요.

php artisan migrate

이미 실행된 마이그레이션와 아직 보류 중인 마이그레이션을 확인하려면 migrate:status Artisan 명령을 사용할 수 있습니다.

php artisan migrate:status

--step 옵션을 migrate 명령에 제공하면 명령은 각 마이그레이션을 자체 배치로 실행하므로 나중에 migrate:rollback 명령을 사용하여 개별 마이그레이션을 롤백할 수 있습니다.

php artisan migrate --step

실제로 실행하지 않고 마이그레이션에 의해 실행될 SQL 문을 보려면 migrate 명령에 --pretend 플래그를 제공할 수 있습니다.

php artisan migrate --pretend

마이그레이션 실행 격리

여러 서버에 애플리케이션을 배포하고 배포 프로세스의 일부로 마이그레이션을 실행하는 경우 두 서버가 동시에 데이터베이스 마이그레이션을 시도하는 것을 원하지 않을 것입니다. 이를 방지하려면 migrate 명령을 호출할 때 isolated 옵션을 사용할 수 있습니다.

isolated 옵션이 제공되면 Laravel은 마이그레이션 실행을 시도하기 전에 애플리케이션의 캐시 드라이버를 사용하여 원자 잠금을 획득합니다. 해당 잠금이 유지되는 동안 migrate 명령을 실행하려는 다른 모든 시도는 실행되지 않습니다. 그러나 명령은 성공적인 종료 상태 코드로 종료됩니다.

php artisan migrate --isolated

[!WARNING] 이 기능을 활용하려면 애플리케이션에서 memcached, redis, dynamodb, database, file 또는 array 캐시 드라이버를 애플리케이션의 기본 캐시 드라이버로 사용해야 합니다. 또한 모든 서버는 동일한 중앙 캐시 서버와 통신해야 합니다.

프로덕션에서 마이그레이션을 강제로 실행

일부 마이그레이션 작업은 파괴적이므로 데이터가 손실될 수 있습니다. 프로덕션 데이터베이스에 대해 이러한 명령을 실행하지 못하도록 보호하기 위해 명령이 실행되기 전에 확인 메시지가 표시됩니다. 프롬프트 없이 명령을 강제로 실행하려면 --force 플래그를 사용하십시오.

php artisan migrate --force

마이그레이션 롤백

최신 마이그레이션 작업을 롤백하려면 rollback Artisan 명령을 사용할 수 있습니다. 이 명령은 여러 마이그레이션 파일을 포함할 수 있는 마이그레이션의 마지막 "배치"를 롤백합니다.

php artisan migrate:rollback

rollback 명령에 step 옵션을 제공하여 제한된 수의 마이그레이션을 롤백할 수 있습니다. 예를 들어 다음 명령은 마지막 5개의 마이그레이션을 롤백합니다.

php artisan migrate:rollback --step=5

batch 옵션을 rollback 명령에 제공하여 마이그레이션의 특정 "배치"를 롤백할 수 있습니다. 여기서 batch 옵션은 응용 프로그램의 migrations 데이터베이스 테이블 내의 배치 값에 해당합니다. 예를 들어 다음 명령은 배치 3개의 모든 마이그레이션을 롤백합니다.

php artisan migrate:rollback --batch=3

실제로 실행하지 않고 마이그레이션에 의해 실행될 SQL 문을 보려면 migrate:rollback 명령에 --pretend 플래그를 제공할 수 있습니다.

php artisan migrate:rollback --pretend

migrate:reset 명령은 애플리케이션의 모든 마이그레이션을 롤백합니다.

php artisan migrate:reset

단일 명령을 사용하여 롤백 및 마이그레이션

migrate:refresh 명령은 모든 마이그레이션을 롤백한 다음 migrate 명령을 실행합니다. 이 명령은 전체 데이터베이스를 효과적으로 다시 생성합니다.

php artisan migrate:refresh

# Refresh the database and run all database seeds...
php artisan migrate:refresh --seed

refresh 명령에 step 옵션을 제공하여 제한된 수의 마이그레이션을 롤백하고 다시 마이그레이션할 수 있습니다. 예를 들어 다음 명령은 마지막 5개의 마이그레이션을 롤백하고 다시 마이그레이션합니다.

php artisan migrate:refresh --step=5

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

migrate:fresh 명령은 데이터베이스에서 모든 테이블을 삭제한 다음 migrate 명령을 실행합니다.

php artisan migrate:fresh

php artisan migrate:fresh --seed

기본적으로 migrate:fresh 명령은 기본 데이터베이스 연결에서만 테이블을 삭제합니다. 그러나 --database 옵션을 사용하여 마이그레이션해야 하는 데이터베이스 연결을 지정할 수 있습니다. 데이터베이스 연결 이름은 애플리케이션의 database 구성 파일에 정의된 연결과 일치해야 합니다.

php artisan migrate:fresh --database=admin

[!WARNING] migrate:fresh 명령은 접두사에 관계없이 모든 데이터베이스 테이블을 삭제합니다. 이 명령은 다른 애플리케이션과 공유되는 데이터베이스에서 개발할 때 주의해서 사용해야 합니다.

테이블 (Tables)

테이블 생성

새 데이터베이스 테이블을 생성하려면 Schema 파사드에서 create 메서드를 사용하세요. 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, hasColumnhasIndex 메서드를 사용하여 테이블, 열 또는 인덱스의 존재를 확인할 수 있습니다.

if (Schema::hasTable('users')) {
// The "users" table exists...
}

if (Schema::hasColumn('users', 'email')) {
// The "users" table exists and has an "email" column...
}

if (Schema::hasIndex('users', ['email'], 'unique')) {
// The "users" table exists and has a unique index on the "email" column...
}

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

애플리케이션의 기본 연결이 아닌 데이터베이스 연결에서 스키마 작업을 수행하려면 connection 메서드를 사용하세요.

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

또한 몇 가지 다른 속성과 메서드를 사용하여 테이블 생성의 다른 측면을 정의할 수 있습니다. MariaDB 또는 MySQL을 사용할 때 engine 속성을 사용하여 테이블의 스토리지 엔진을 지정할 수 있습니다.

Schema::create('users', function (Blueprint $table) {
$table->engine('InnoDB');

// ...
});

charsetcollation 속성은 MariaDB 또는 MySQL을 사용할 때 생성된 테이블에 대한 문자 집합 및 데이터 정렬을 지정하는 데 사용할 수 있습니다.

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('Business calculations');

// ...
});

테이블 수정

Schema 파사드의 table 메서드는 기존 테이블을 업데이트하는 데 사용될 수 있습니다. create 메서드와 마찬가지로 table 메서드는 테이블 이름과 테이블에 열이나 인덱스를 추가하는 데 사용할 수 있는 Blueprint 인스턴스를 수신하는 클로저라는 두 가지 인수를 허용합니다.

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이 규칙 기반으로 이름을 부여하는 대신 마이그레이션 파일에서 외래 키 제약 조건에 명시적인 이름을 지정했는지 확인해야 합니다. 그렇지 않으면 외래 키 제약 조건 이름이 이전 테이블 이름을 참조하게 됩니다.

컬럼 (Columns)

컬럼 생성

Schema 파사드의 table 메서드는 기존 테이블을 업데이트하는 데 사용될 수 있습니다. create 메서드와 마찬가지로 table 메서드는 테이블 이름과 테이블에 열을 추가하는 데 사용할 수 있는 Illuminate\Database\Schema\Blueprint 인스턴스를 수신하는 클로저라는 두 가지 인수를 허용합니다.

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

Schema::table('users', function (Blueprint $table) {
$table->integer('votes');
});

사용 가능한 컬럼 타입

스키마 빌더의 블루프린트는 데이터베이스 테이블에 추가할 수 있는 다양한 컬럼 타입에 해당하는 여러 메서드를 제공합니다. 사용 가능한 각 메서드는 아래 표에 나열되어 있습니다.

부울 유형

문자열 및 텍스트 유형

숫자 유형

날짜 및 시간 유형

바이너리 유형

객체 및 Json 유형

UUID 및 ULID 유형

공간 유형

관계 유형

전문 유형

bigIncrements()

bigIncrements 메서드는 자동 증가 UNSIGNED BIGINT(기본 키) 해당 열을 생성합니다.

$table->bigIncrements('id');

bigInteger()

bigInteger 메서드는 BIGINT 해당 열을 생성합니다.

$table->bigInteger('votes');

binary()

binary 메서드는 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()

boolean 메서드는 BOOLEAN 해당 열을 생성합니다.

$table->boolean('confirmed');

char()

char 메서드는 주어진 길이의 CHAR 해당 열을 생성합니다.

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

dateTimeTz()

dateTimeTz 메서드는 선택적 소수 초 정밀도를 사용하여 DATETIME(시간대 포함) 해당 열을 생성합니다.

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

dateTime()

dateTime 메서드는 선택적 소수 초 정밀도를 사용하여 DATETIME에 해당하는 열을 생성합니다.

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

date()

date 메서드는 DATE 해당 열을 생성합니다.

$table->date('created_at');

decimal()

decimal 메서드는 주어진 정밀도(총 자릿수)와 소수 자릿수(십진수)를 사용하여 DECIMAL에 해당하는 열을 생성합니다.

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

double()

double 메서드는 DOUBLE 해당 열을 생성합니다.

$table->double('amount');

enum()

enum 메서드는 주어진 유효한 값을 사용하여 ENUM에 해당하는 열을 생성합니다.

$table->enum('difficulty', ['easy', 'hard']);

물론 허용되는 값의 배열을 수동으로 정의하는 대신 Enum::cases() 메서드를 사용할 수도 있습니다.

use App\Enums\Difficulty;

$table->enum('difficulty', Difficulty::cases());

float()

float 메서드는 지정된 정밀도로 FLOAT에 해당하는 열을 생성합니다.

$table->float('amount', precision: 53);

foreignId()

foreignId 메서드는 UNSIGNED BIGINT 해당 열을 생성합니다.

$table->foreignId('user_id');

foreignIdFor()

foreignIdFor 메서드는 지정된 모델 클래스에 대해 {column}_id 해당 열을 추가합니다. 열 유형은 모델 키 유형에 따라 UNSIGNED BIGINT, CHAR(36) 또는 CHAR(26)입니다.

$table->foreignIdFor(User::class);

foreignUlid()

foreignUlid 메서드는 ULID 해당 열을 생성합니다.

$table->foreignUlid('user_id');

foreignUuid()

foreignUuid 메서드는 UUID 해당 열을 생성합니다.

$table->foreignUuid('user_id');

geography()

geography 메서드는 지정된 공간 유형 및 SRID(공간 참조 시스템 식별자)를 사용하여 GEOGRAPHY에 해당하는 열을 생성합니다.

$table->geography('coordinates', subtype: 'point', srid: 4326);

[!NOTE] 공간 유형 지원은 데이터베이스 드라이버에 따라 다릅니다. 데이터베이스 설명서를 참조하세요. 응용 프로그램이 PostgreSQL 데이터베이스를 활용하는 경우 geography 방법을 사용하기 전에 PostGIS 확장을 설치해야 합니다.

geometry()

geometry 메서드는 지정된 공간 유형 및 SRID(공간 참조 시스템 식별자)를 사용하여 GEOMETRY에 해당하는 열을 생성합니다.

$table->geometry('positions', subtype: 'point', srid: 0);

[!NOTE] 공간 유형 지원은 데이터베이스 드라이버에 따라 다릅니다. 데이터베이스 설명서를 참조하세요. 응용 프로그램이 PostgreSQL 데이터베이스를 활용하는 경우 geometry 방법을 사용하기 전에 PostGIS 확장을 설치해야 합니다.

id()

id 메서드는 bigIncrements 메서드의 별칭입니다. 기본적으로 이 메서드는 id 열을 생성합니다. 그러나 열에 다른 이름을 할당하려면 열 이름을 전달할 수 있습니다.

$table->id();

increments()

increments 메서드는 자동 증가 UNSIGNED INTEGER 해당 열을 기본 키로 생성합니다.

$table->increments('id');

integer()

integer 메서드는 INTEGER 해당 열을 생성합니다.

$table->integer('votes');

ipAddress()

ipAddress 메서드는 VARCHAR 해당 열을 생성합니다.

$table->ipAddress('visitor');

PostgreSQL를 사용하면 INET 열이 생성됩니다.

json()

json 메서드는 JSON 해당 열을 생성합니다.

$table->json('options');

SQLite를 사용하면 TEXT 열이 생성됩니다.

jsonb()

jsonb 메서드는 JSONB 해당 열을 생성합니다.

$table->jsonb('options');

SQLite를 사용하면 TEXT 열이 생성됩니다.

longText()

longText 메서드는 LONGTEXT 해당 열을 생성합니다.

$table->longText('description');

MySQL 또는 MariaDB를 활용하는 경우 LONGBLOB에 해당하는 열을 생성하기 위해 열에 binary 문자 집합을 적용할 수 있습니다.

$table->longText('data')->charset('binary'); // LONGBLOB

macAddress()

macAddress 메서드는 MAC 주소를 보유하기 위한 열을 생성합니다. PostgreSQL와 같은 일부 데이터베이스 시스템에는 이러한 유형의 데이터에 대한 전용 열 유형이 있습니다. 다른 데이터베이스 시스템에서는 해당 문자열 열을 사용합니다.

$table->macAddress('device');

mediumIncrements()

mediumIncrements 메서드는 자동 증가 UNSIGNED MEDIUMINT 해당 열을 기본 키로 생성합니다.

$table->mediumIncrements('id');

mediumInteger()

mediumInteger 메서드는 MEDIUMINT 해당 열을 생성합니다.

$table->mediumInteger('votes');

mediumText()

mediumText 메서드는 MEDIUMTEXT 해당 열을 생성합니다.

$table->mediumText('description');

MySQL 또는 MariaDB를 활용하는 경우 MEDIUMBLOB에 해당하는 열을 생성하기 위해 열에 binary 문자 집합을 적용할 수 있습니다.

$table->mediumText('data')->charset('binary'); // MEDIUMBLOB

morphs()

morphs 메서드는 {column}_id 해당 컬럼과 {column}_type VARCHAR 해당 컬럼을 추가하는 편의 메서드이다. {column}_id의 열 유형은 모델 키 유형에 따라 UNSIGNED BIGINT, CHAR(36) 또는 CHAR(26)입니다.

이 방법은 다형성 Eloquent 관계에 필요한 열을 정의할 때 사용하기 위한 것입니다. 다음 예에서는 taggable_idtaggable_type 열이 생성됩니다.

$table->morphs('taggable');

nullableMorphs()

이 방법은 morphs 방법과 유사합니다. 그러나 생성된 열은 "nullable"입니다.

$table->nullableMorphs('taggable');

nullableUlidMorphs()

이 방법은 ulidMorphs 방법과 유사합니다. 그러나 생성된 열은 "nullable"입니다.

$table->nullableUlidMorphs('taggable');

nullableUuidMorphs()

이 방법은 uuidMorphs 방법과 유사합니다. 그러나 생성된 열은 "nullable"입니다.

$table->nullableUuidMorphs('taggable');

rememberToken()

rememberToken 메서드는 현재 "기억하기"인증 토큰을 저장하기 위한 nullable VARCHAR(100) 해당 열을 생성합니다.

$table->rememberToken();

set()

set 메서드는 주어진 유효한 값 목록을 사용하여 SET에 해당하는 열을 생성합니다.

$table->set('flavors', ['strawberry', 'vanilla']);

smallIncrements()

smallIncrements 메서드는 자동 증가 UNSIGNED SMALLINT 해당 열을 기본 키로 생성합니다.

$table->smallIncrements('id');

smallInteger()

smallInteger 메서드는 SMALLINT 해당 열을 생성합니다.

$table->smallInteger('votes');

softDeletesTz()

softDeletesTz 메서드는 선택적 소수 초 정밀도를 사용하여 null 허용 deleted_at TIMESTAMP(시간대 포함) 해당 열을 추가합니다. 이 열은 Eloquent의 "일시 삭제" 기능에 필요한 deleted_at 타임스탬프를 저장하기 위한 것입니다.

$table->softDeletesTz('deleted_at', precision: 0);

softDeletes()

softDeletes 메서드는 선택적 소수 초 정밀도를 사용하여 null 허용 deleted_at TIMESTAMP 해당 열을 추가합니다. 이 열은 Eloquent의 "일시 삭제" 기능에 필요한 deleted_at 타임스탬프를 저장하기 위한 것입니다.

$table->softDeletes('deleted_at', precision: 0);

string()

string 메서드는 지정된 길이의 VARCHAR 해당 열을 생성합니다.

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

text()

text 메서드는 TEXT 해당 열을 생성합니다.

$table->text('description');

MySQL 또는 MariaDB를 활용하는 경우 BLOB에 해당하는 열을 생성하기 위해 열에 binary 문자 집합을 적용할 수 있습니다.

$table->text('data')->charset('binary'); // BLOB

timeTz()

timeTz 메서드는 선택적 소수 초 정밀도를 사용하여 TIME(시간대 포함) 해당 열을 생성합니다.

$table->timeTz('sunrise', precision: 0);

time()

time 메서드는 선택적 소수 초 정밀도를 사용하여 TIME에 해당하는 열을 생성합니다.

$table->time('sunrise', precision: 0);

timestampTz()

timestampTz 메서드는 선택적 소수 초 정밀도를 사용하여 TIMESTAMP(시간대 포함) 해당 열을 생성합니다.

$table->timestampTz('added_at', precision: 0);

timestamp()

timestamp 메서드는 선택적 소수 초 정밀도를 사용하여 TIMESTAMP에 해당하는 열을 생성합니다.

$table->timestamp('added_at', precision: 0);

timestampsTz()

timestampsTz 메서드는 선택적 소수 초 정밀도를 사용하여 created_atupdated_at TIMESTAMP(시간대 포함) 해당 열을 생성합니다.

$table->timestampsTz(precision: 0);

timestamps()

timestamps 메서드는 선택적 소수 초 정밀도를 사용하여 created_atupdated_at TIMESTAMP 해당 열을 생성합니다.

$table->timestamps(precision: 0);

tinyIncrements()

tinyIncrements 메서드는 자동 증가 UNSIGNED TINYINT 해당 열을 기본 키로 생성합니다.

$table->tinyIncrements('id');

tinyInteger()

tinyInteger 메서드는 TINYINT 해당 열을 생성합니다.

$table->tinyInteger('votes');

tinyText()

tinyText 메서드는 TINYTEXT 해당 열을 생성합니다.

$table->tinyText('notes');

MySQL 또는 MariaDB를 활용하는 경우 TINYBLOB에 해당하는 열을 생성하기 위해 열에 binary 문자 집합을 적용할 수 있습니다.

$table->tinyText('data')->charset('binary'); // TINYBLOB

unsignedBigInteger()

unsignedBigInteger 메서드는 UNSIGNED BIGINT 해당 열을 생성합니다.

$table->unsignedBigInteger('votes');

unsignedInteger()

unsignedInteger 메서드는 UNSIGNED INTEGER 해당 열을 생성합니다.

$table->unsignedInteger('votes');

unsignedMediumInteger()

unsignedMediumInteger 메서드는 UNSIGNED MEDIUMINT 해당 열을 생성합니다.

$table->unsignedMediumInteger('votes');

unsignedSmallInteger()

unsignedSmallInteger 메서드는 UNSIGNED SMALLINT 해당 열을 생성합니다.

$table->unsignedSmallInteger('votes');

unsignedTinyInteger()

unsignedTinyInteger 메서드는 UNSIGNED TINYINT 해당 열을 생성합니다.

$table->unsignedTinyInteger('votes');

ulidMorphs()

ulidMorphs 메서드는 {column}_id CHAR(26) 해당 열과 {column}_type VARCHAR 해당 열을 추가하는 편의 메서드입니다.

이 방법은 ULID 식별자를 사용하는 다형성 Eloquent 관계에 필요한 열을 정의할 때 사용하기 위한 것입니다. 다음 예에서는 taggable_idtaggable_type 열이 생성됩니다.

$table->ulidMorphs('taggable');

uuidMorphs()

uuidMorphs 메서드는 {column}_id CHAR(36) 해당 열과 {column}_type VARCHAR 해당 열을 추가하는 편의 메서드입니다.

이 방법은 UUID 식별자를 사용하는 다형성 Eloquent 관계에 필요한 열을 정의할 때 사용하기 위한 것입니다. 다음 예에서는 taggable_idtaggable_type 열이 생성됩니다.

$table->uuidMorphs('taggable');

ulid()

ulid 메서드는 ULID 해당 열을 생성합니다.

$table->ulid('id');

uuid()

uuid 메서드는 UUID 해당 열을 생성합니다.

$table->uuid('id');

vector()

vector 메서드는 vector 해당 열을 생성합니다.

$table->vector('embedding', dimensions: 100);

PostgreSQL를 활용하는 경우 vector 열을 생성하기 전에 pgvector 확장을 로드해야 합니다.

Schema::ensureVectorExtensionExists();

year()

year 메서드는 YEAR 해당 열을 생성합니다.

$table->year('birth_year');

컬럼 수정자

위에 나열된 열 유형 외에도 데이터베이스 테이블에 열을 추가할 때 사용할 수 있는 여러 가지 열 "수정자"가 있습니다. 예를 들어, 열을 "nullable"로 만들려면 nullable 메서드를 사용할 수 있습니다.

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

Schema::table('users', function (Blueprint $table) {
$table->string('email')->nullable();
});

다음 표에는 사용 가능한 모든 열 수정자가 포함되어 있습니다. 이 목록에는 색인 수정자가 포함되지 않습니다.

수정자설명
->after('column')다른 열(MariaDB / MySQL) "뒤에" 열을 배치합니다.
->autoIncrement()INTEGER 열을 자동 증가(기본 키)로 설정합니다.
->charset('utf8mb4')열(MariaDB / MySQL)에 대한 문자 집합을 지정합니다.
->collation('utf8mb4_unicode_ci')열의 데이터 정렬을 지정합니다.
->comment('my comment')열(MariaDB / MySQL / PostgreSQL)에 설명을 추가합니다.
->default($value)열의 "기본값"을 지정합니다.
->first()테이블(MariaDB / MySQL)에 "첫 번째" 열을 배치합니다.
->from($integer)자동 증가 필드(MariaDB / MySQL / PostgreSQL)의 시작 값을 설정합니다.
->instant()인스턴트 작업(MySQL)을 사용하여 열을 추가하거나 수정합니다.
->invisible()열을 SELECT * 쿼리 (MariaDB / MySQL)에 "보이지 않게" 만듭니다.
->lock($mode)컬럼 조작(MySQL)에 대한 잠금 모드를 지정하십시오.
->nullable($value = true)NULL 값이 열에 삽입되도록 허용합니다.
->storedAs($expression)저장된 생성 열(MariaDB / MySQL / PostgreSQL / SQLite)을 만듭니다.
->unsigned()INTEGER 열을 UNSIGNED(MariaDB / MySQL)로 설정합니다.
->useCurrent()CURRENT_TIMESTAMP를 기본값으로 사용하도록 TIMESTAMP 열을 설정합니다.
->useCurrentOnUpdate()레코드가 업데이트될 때 CURRENT_TIMESTAMP를 사용하도록 TIMESTAMP 열을 설정합니다(MariaDB / MySQL).
->virtualAs($expression)가상 생성 열(MariaDB / MySQL / SQLite)을 만듭니다.
->generatedAs($expression)지정된 순서 옵션(PostgreSQL)을 사용하여 ID 열을 만듭니다.
->always()ID 열(PostgreSQL)에 대한 입력보다 시퀀스 값의 우선순위를 정의합니다.

기본 표현식

default 수정자는 값 또는 Illuminate\Database\Query\Expression 인스턴스를 받습니다. Expression 인스턴스를 사용하면 Laravel이 값을 따옴표로 감싸지 않으며, 데이터베이스 고유 기능을 사용할 수 있게 됩니다. 이것이 특히 유용한 상황 중 하나는 JSON 컬럼에 기본값을 할당해야 하는 경우입니다.

<?php

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

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('flights', function (Blueprint $table) {
$table->id();
$table->json('movies')->default(new Expression('(JSON_ARRAY())'));
$table->timestamps();
});
}
};

[!WARNING] 기본 표현식 지원은 데이터베이스 드라이버, 데이터베이스 버전 및 필드 유형에 따라 다릅니다. 데이터베이스 설명서를 참조하세요.

열 순서

MariaDB 또는 MySQL 데이터베이스를 사용하는 경우 after 메서드를 사용하여 스키마의 기존 열 뒤에 열을 추가할 수 있습니다.

$table->after('password', function (Blueprint $table) {
$table->string('address_line1');
$table->string('address_line2');
$table->string('city');
});

즉각적인 컬럼 작업

MySQL을 사용할 때 열 정의에 instant 수정자를 연결하여 MySQL의 "인스턴트" 알고리즘을 사용하여 열을 추가하거나 수정해야 함을 나타낼 수 있습니다. 이 알고리즘을 사용하면 전체 테이블을 다시 작성하지 않고도 특정 스키마 변경을 수행할 수 있으므로 테이블 크기에 관계없이 거의 즉시 변경이 가능합니다.

$table->string('name')->nullable()->instant();

즉각적인 열 추가는 테이블 끝에만 열을 추가할 수 있으므로 instant 수정자는 after 또는 first 수정자와 결합될 수 없습니다. 또한 알고리즘은 모든 열 유형이나 작업을 지원하지 않습니다. 요청한 작업이 호환되지 않으면 MySQL에서 오류가 발생합니다.

즉각적인 컬럼 수정과 호환되는 작업을 확인하려면 MySQL 문서를 참조하세요.

DDL 잠금

MySQL을 사용하는 경우 lock 수정자를 열, 인덱스 또는 외래 키 정의에 연결하여 스키마 작업 중 테이블 잠금을 제어할 수 있습니다. MySQL는 여러 잠금 모드를 지원합니다. none는 동시 읽기 및 쓰기를 허용하고, shared는 동시 읽기를 허용하지만 쓰기를 차단하며, exclusive는 모든 동시 액세스를 차단하고, default는 MySQL가 가장 적절한 모드를 선택할 수 있도록 합니다.

$table->string('name')->lock('none');

$table->index('email')->lock('shared');

요청된 잠금 모드가 작업과 호환되지 않으면 MySQL에서 오류가 발생합니다. lock 수정자는 instant 수정자와 결합되어 스키마 변경을 더욱 최적화할 수 있습니다.

$table->string('name')->instant()->lock('none');

컬럼 수정

change 메서드를 사용하면 기존 컬럼의 타입과 속성을 수정할 수 있습니다. 예를 들어, string 컬럼의 크기를 늘릴 수 있습니다. change 메서드가 실제로 작동하는 모습을 보기 위해 name 컬럼의 크기를 25에서 50으로 늘려 보겠습니다. 이를 위해 컬럼의 새 상태를 정의한 다음 change 메서드를 호출하면 됩니다.

Schema::table('users', function (Blueprint $table) {
$table->string('name', 50)->change();
});

열을 수정할 때 열 정의에 유지하려는 모든 수정자를 명시적으로 포함해야 합니다. 누락된 속성은 삭제됩니다. 예를 들어, unsigned, defaultcomment 속성을 유지하려면 열을 변경할 때 각 수정자를 명시적으로 호출해야 합니다.

Schema::table('users', function (Blueprint $table) {
$table->integer('votes')->unsigned()->default(1)->comment('my comment')->change();
});

change 메서드는 열의 인덱스를 변경하지 않습니다. 따라서 인덱스 수정자를 사용하여 열을 수정할 때 인덱스를 명시적으로 추가하거나 삭제할 수 있습니다.

// Add an index...
$table->bigIncrements('id')->primary()->change();

// Drop an index...
$table->char('postal_code', 10)->unique(false)->change();

컬럼 이름 변경

열 이름을 바꾸려면 스키마 빌더에서 제공하는 renameColumn 메서드를 사용할 수 있습니다.

Schema::table('users', function (Blueprint $table) {
$table->renameColumn('from', 'to');
});

컬럼 삭제

열을 삭제하려면 스키마 빌더에서 dropColumn 메서드를 사용할 수 있습니다.

Schema::table('users', function (Blueprint $table) {
$table->dropColumn('votes');
});

열 이름 배열을 dropColumn 메서드에 전달하여 테이블에서 여러 열을 삭제할 수 있습니다.

Schema::table('users', function (Blueprint $table) {
$table->dropColumn(['votes', 'avatar', 'location']);
});

사용 가능한 명령 별명

Laravel은 일반적인 유형의 열 삭제와 관련된 몇 가지 편리한 방법을 제공합니다. 각 방법은 아래 표에 설명되어 있습니다.

명령설명
$table->dropMorphs('morphable');morphable_idmorphable_type 열을 삭제합니다.
$table->dropRememberToken();remember_token 열을 삭제합니다.
$table->dropSoftDeletes();deleted_at 열을 삭제합니다.
$table->dropSoftDeletesTz();dropSoftDeletes() 메서드의 별칭입니다.
$table->dropTimestamps();created_atupdated_at 열을 삭제합니다.
$table->dropTimestampsTz();dropTimestamps() 메서드의 별칭입니다.

인덱스 (Indexes)

인덱스 생성

Laravel 스키마 빌더는 여러 유형의 인덱스를 지원합니다. 다음 예에서는 새 email 열을 생성하고 해당 값이 고유해야 함을 지정합니다. 인덱스를 생성하려면 unique 메서드를 열 정의에 연결할 수 있습니다.

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

Schema::table('users', function (Blueprint $table) {
$table->string('email')->unique();
});

또는 열을 정의한 후 인덱스를 생성할 수도 있습니다. 이렇게 하려면 스키마 빌더 청사진에서 unique 메서드를 호출해야 합니다. 이 메서드는 고유 인덱스를 수신해야 하는 열의 이름을 허용합니다.

$table->unique('email');

복합(또는 복합) 인덱스를 생성하기 위해 열 배열을 인덱스 메서드에 전달할 수도 있습니다:

$table->index(['account_id', 'created_at']);

인덱스를 생성할 때 Laravel은 테이블, 열 이름 및 인덱스 유형을 기반으로 인덱스 이름을 자동으로 생성하지만, 인덱스 이름을 직접 지정하기 위해 메서드에 두 번째 인수를 전달할 수도 있습니다.

$table->unique('email', 'unique_email');

사용 가능한 인덱스 유형

Laravel의 스키마 빌더 청사진 클래스는 Laravel에서 지원하는 각 유형의 인덱스를 생성하는 방법을 제공합니다. 각 인덱스 메서드는 인덱스 이름을 지정하기 위해 선택적 두 번째 인수를 허용합니다. 생략하면 인덱스에 사용된 테이블 및 열 이름과 인덱스 유형에서 이름이 파생됩니다. 사용 가능한 각 인덱스 방법은 아래 표에 설명되어 있습니다.

명령설명
$table->primary('id');기본 키를 추가합니다.
$table->primary(['id', 'parent_id']);복합 키를 추가합니다.
$table->unique('email');고유 인덱스를 추가합니다.
$table->index('state');인덱스를 추가합니다.
$table->fullText('body');전체 텍스트 색인(MariaDB / MySQL / PostgreSQL)을 추가합니다.
$table->fullText('body')->language('english');지정된 언어(PostgreSQL)의 전체 텍스트 색인을 추가합니다.
$table->spatialIndex('location');공간 인덱스를 추가합니다(SQLite 제외).

온라인 인덱스 생성

기본적으로 큰 테이블에 인덱스를 생성하면 테이블이 잠기고 인덱스가 작성되는 동안 읽기 또는 쓰기가 차단될 수 있습니다. PostgreSQL 또는 SQL Server를 사용하는 경우 online 메서드를 인덱스 정의에 연결하여 테이블을 잠그지 않고 인덱스를 생성할 수 있습니다. 그러면 애플리케이션이 인덱스 생성 중에 데이터를 계속 읽고 쓸 수 있습니다.

$table->string('email')->unique()->online();

PostgreSQL를 사용하는 경우 인덱스 생성 문에 CONCURRENTLY 옵션이 추가됩니다. SQL Server를 사용하는 경우 WITH (online = on) 옵션이 추가됩니다.

인덱스 이름 변경

인덱스 이름을 바꾸려면 스키마 빌더 청사진에서 제공하는 renameIndex 방법을 사용할 수 있습니다. 이 메서드는 현재 인덱스 이름을 첫 번째 인수로, 원하는 이름을 두 번째 인수로 받아들입니다.

$table->renameIndex('from', 'to')

인덱스 삭제

인덱스를 삭제하려면 인덱스 이름을 지정해야 합니다. 기본적으로 Laravel은 테이블 이름, 인덱싱된 열 이름 및 인덱스 유형을 기반으로 인덱스 이름을 자동으로 할당합니다. 다음은 몇 가지 예입니다.

명령설명
$table->dropPrimary('users_id_primary');"users" 테이블에서 기본 키를 삭제합니다.
$table->dropUnique('users_email_unique');"users" 테이블에서 고유 인덱스를 삭제합니다.
$table->dropIndex('geo_state_index');"geo" 테이블에서 기본 인덱스를 삭제합니다.
$table->dropFullText('posts_body_fulltext');"posts" 테이블에서 전체 텍스트 색인을 삭제합니다.
$table->dropSpatialIndex('geo_location_spatialindex');"geo" 테이블에서 공간 인덱스를 삭제합니다(SQLite 제외).

인덱스를 삭제하는 메서드에 열 배열을 전달하면 테이블 이름, 열 및 인덱스 유형을 기반으로 기존 인덱스 이름이 생성됩니다.

Schema::table('geo', function (Blueprint $table) {
$table->dropIndex(['state']); // Drops index 'geo_state_index'
});

외래 키 제약 조건

Laravel은 또한 데이터베이스 수준에서 참조 무결성을 강제하는 데 사용되는 외래 키 제약 조건 생성을 지원합니다. 예를 들어, users 테이블의 id 열을 참조하는 posts 테이블에 user_id 열을 정의해 보겠습니다.

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

Schema::table('posts', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');

$table->foreign('user_id')->references('id')->on('users');
});

이 구문은 다소 장황하므로 Laravel은 더 나은 개발자 환경을 제공하기 위해 규칙을 사용하는 더 간결한 추가 방법을 제공합니다. foreignId 메서드를 사용하여 열을 생성할 때 위의 예는 다음과 같이 다시 작성할 수 있습니다.

Schema::table('posts', function (Blueprint $table) {
$table->foreignId('user_id')->constrained();
});

foreignId 메서드는 UNSIGNED BIGINT에 해당하는 열을 생성하는 반면, constrained 메서드는 규칙을 사용하여 참조되는 테이블과 열을 결정합니다. 테이블 이름이 Laravel의 규칙과 일치하지 않는 경우 수동으로 constrained 메서드에 제공할 수 있습니다. 또한 생성된 인덱스에 할당되어야 하는 이름도 지정할 수 있습니다.

Schema::table('posts', function (Blueprint $table) {
$table->foreignId('user_id')->constrained(
table: 'users', indexName: 'posts_user_id'
);
});

제약 조건의 "삭제 시" 및 "업데이트 시" 속성에 대해 원하는 작업을 지정할 수도 있습니다.

$table->foreignId('user_id')
->constrained()
->onUpdate('cascade')
->onDelete('cascade');

다음 작업에 대한 대체 표현 구문도 제공됩니다.

방법설명
$table->cascadeOnUpdate();업데이트는 계단식으로 이루어져야 합니다.
$table->restrictOnUpdate();업데이트를 제한해야 합니다.
$table->nullOnUpdate();업데이트에서는 외래 키 값을 null로 설정해야 합니다.
$table->noActionOnUpdate();업데이트에 대한 조치가 없습니다.
$table->cascadeOnDelete();삭제는 계단식으로 이루어져야 합니다.
$table->restrictOnDelete();삭제는 제한되어야 합니다.
$table->nullOnDelete();삭제 시 외래 키 값을 null로 설정해야 합니다.
$table->noActionOnDelete();하위 레코드가 있는 경우 삭제를 방지합니다.

추가 열 수정자constrained 메서드 전에 호출되어야 합니다.

$table->foreignId('user_id')
->nullable()
->constrained();

외래 키 삭제

외래 키를 삭제하려면 dropForeign 메서드를 사용하여 삭제할 외래 키 제약 조건의 이름을 인수로 전달하면 됩니다. 외래 키 제약 조건은 인덱스와 동일한 명명 규칙을 사용합니다. 즉, 외래 키 제약 조건 이름은 테이블 이름과 제약 조건의 열을 기반으로 하며 그 뒤에 "_foreign" 접미사가 옵니다.

$table->dropForeign('posts_user_id_foreign');

또는 외래 키를 보유하는 열 이름이 포함된 배열을 dropForeign 메서드에 전달할 수도 있습니다. 배열은 Laravel의 제약 조건 명명 규칙을 사용하여 외래 키 제약 조건 이름으로 변환됩니다.

$table->dropForeign(['user_id']);

외래 키 제약 조건 전환

다음 방법을 사용하여 마이그레이션 내에서 외래 키 제약 조건을 활성화하거나 비활성화할 수 있습니다.

Schema::enableForeignKeyConstraints();

Schema::disableForeignKeyConstraints();

Schema::withoutForeignKeyConstraints(function () {
// Constraints disabled within this closure...
});

[!WARNING] SQLite는 기본적으로 외래 키 제약 조건을 비활성화합니다. SQLite를 사용하는 경우 마이그레이션에서 생성을 시도하기 전에 데이터베이스 구성에서 외래 키 지원을 활성화했는지 확인하세요.

이벤트 (Events)

편의상 각 마이그레이션 작업은 디스패치 및 이벤트입니다. 다음 이벤트는 모두 기본 Illuminate\Database\Events\MigrationEvent 클래스를 확장합니다.

수업설명
Illuminate\Database\Events\MigrationsStarted마이그레이션의 배치가 실행되려고 합니다.
Illuminate\Database\Events\MigrationsEnded마이그레이션의 배치가 실행을 완료했습니다.
Illuminate\Database\Events\MigrationStarted단일 마이그레이션이 곧 실행될 예정입니다.
Illuminate\Database\Events\MigrationEnded단일 마이그레이션 실행이 완료되었습니다.
Illuminate\Database\Events\NoPendingMigrations마이그레이션 명령이 보류 중인 마이그레이션을 찾지 못했습니다.
Illuminate\Database\Events\SchemaDumped데이터베이스 스키마 덤프가 완료되었습니다.
Illuminate\Database\Events\SchemaLoaded기존 데이터베이스 스키마 덤프가 로드되었습니다.