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

1 개요[ | ]

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

https://laravel.com/docs/11.x/migrations

2 소개[ | ]

마이그레이션은 데이터베이스의 버전 관리와 같아서 팀이 애플리케이션의 데이터베이스 스키마 정의를 정의하고 공유할 수 있게 해줍니다. 만약 소스 컨트롤에서 변경사항을 가져온 후 동료에게 로컬 데이터베이스 스키마에 수동으로 컬럼을 추가하라고 한 적이 있다면, 이는 데이터베이스 마이그레이션이 해결하는 문제에 직면한 것입니다.

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

3 마이그레이션 생성[ | ]

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

php artisan make:migration create_flights_table

Laravel은 마이그레이션의 이름을 사용하여 테이블 이름과 마이그레이션이 새로운 테이블을 생성하는지 여부를 추측하려고 합니다. Laravel이 마이그레이션 이름에서 테이블 이름을 결정할 수 있는 경우, 지정된 테이블로 미리 채워진 마이그레이션 파일을 생성합니다. 그렇지 않은 경우, 마이그레이션 파일에서 테이블을 수동으로 지정할 수 있습니다.

생성된 마이그레이션에 대해 커스텀 경로를 지정하고 싶다면 make:migration 명령어를 실행할 때 --path 옵션을 사용할 수 있습니다. 지정된 경로는 애플리케이션의 기본 경로를 기준으로 상대 경로여야 합니다.

Note

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

3.1 마이그레이션 스쿼싱[ | ]

애플리케이션을 개발하면서 시간이 지남에 따라 더 많은 마이그레이션이 축적될 수 있습니다. 이는 database/migrations 디렉토리가 수백 개의 마이그레이션으로 인해 부피가 커지는 문제를 야기할 수 있습니다. 이러한 경우 마이그레이션을 단일 SQL 파일로 "압축(squash)"할 수 있습니다. 이를 시작하려면 다음 명령어를 실행하세요:

php artisan schema:dump

# 현재 데이터베이스 스키마를 덤프하고 기존의 모든 마이그레이션을 제거합니다...
php artisan schema:dump --prune

이 명령어를 실행하면, Laravel은 애플리케이션의 database/schema 디렉토리에 "스키마" 파일을 작성합니다. 스키마 파일의 이름은 데이터베이스 연결에 해당합니다. 이제 데이터베이스를 마이그레이션하려고 할 때 다른 마이그레이션이 실행되지 않은 경우 Laravel은 먼저 사용 중인 데이터베이스 연결의 스키마 파일에 있는 SQL 문을 실행합니다. 그런 다음 스키마 파일의 SQL 문을 실행한 후 남아있는 나머지 마이그레이션을 실행합니다.

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

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

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

Warning

마이그레이션 스쿼싱은 MySQL, PostgreSQL, SQLite 데이터베이스에서만 사용할 수 있으며, 데이터베이스의 명령줄 클라이언트를 활용합니다.

4 마이그레이션 구조[ | ]

마이그레이션 클래스에는 두 가지 메소드 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
{
    /**
     * 마이그레이션을 실행합니다.
     */
    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
{
    // ...
}

5 마이그레이션 실행[ | ]

모든 미처리된 마이그레이션을 실행하려면, migrate Artisan 명령어를 실행하세요:

php artisan migrate

지금까지 실행된 마이그레이션을 확인하려면, migrate:status Artisan 명령어를 사용할 수 있습니다:

php artisan migrate:status

실제 마이그레이션을 실행하지 않고, 실행될 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

5.1 마이그레이션 롤백[ | ]

마지막 마이그레이션 작업을 되돌리려면 rollback Artisan 명령어를 사용할 수 있습니다. 이 명령어는 여러 개의 마이그레이션 파일을 포함할 수 있는 마지막 "배치"의 마이그레이션을 되돌립니다:

php artisan migrate:rollback

제한된 수의 마이그레이션을 되돌리려면 rollback 명령어에 step 옵션을 제공하면 됩니다. 예를 들어, 다음 명령어는 마지막 다섯 개의 마이그레이션을 되돌립니다:

php artisan migrate:rollback --step=5

특정 "배치"의 마이그레이션을 되돌리려면 rollback 명령어에 batch 옵션을 제공하면 됩니다. batch 옵션은 애플리케이션의 마이그레이션 데이터베이스 테이블 내의 배치 값에 해당합니다. 예를 들어, 다음 명령어는 배치 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

# 데이터베이스를 새로고침하고 모든 데이터베이스 시드를 실행합니다...
php artisan migrate:refresh --seed

제한된 수의 마이그레이션을 되돌리고 다시 마이그레이션하려면 refresh 명령어에 step 옵션을 제공하면 됩니다. 예를 들어, 다음 명령어는 마지막 다섯 개의 마이그레이션을 되돌리고 다시 마이그레이션합니다:

php artisan migrate:refresh --step=5
모든 테이블을 삭제하고 마이그레이션하기

migrate:fresh 명령어는 데이터베이스의 모든 테이블을 삭제한 다음 migrate 명령어를 실행합니다:

php artisan migrate:fresh

php artisan migrate:fresh --seed

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

php artisan migrate:fresh --database=admin

Warning

migrate:fresh 명령어는 접두어가 있는 테이블도 모두 삭제합니다. 이 명령어는 다른 애플리케이션과 공유하는 데이터베이스에서 개발할 때 주의해서 사용해야 합니다.

6 테이블[ | ]

6.1 테이블 생성[ | ]

새 데이터베이스 테이블을 생성하려면 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, 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();
});

또한, 테이블 생성 시 다음과 같은 속성과 메소드를 사용하여 다른 측면을 정의할 수 있습니다. MySQL을 사용할 때 테이블의 스토리지 엔진을 지정하려면 engine 속성을 사용할 수 있습니다:

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

    // ...
});

MySQL을 사용할 때 생성된 테이블의 문자 세트와 콜레이션을 지정하려면 charsetcollation 속성을 사용할 수 있습니다:

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

    // ...
});

테이블이 "임시"임을 나타내려면 temporary 메소드를 사용할 수 있습니다. 임시 테이블은 현재 연결된 데이터베이스 세션에서만 보이며 연결이 종료되면 자동으로 삭제됩니다:

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

    // ...
});

데이터베이스 테이블에 "주석(comment)"을 추가하려면 테이블 인스턴스에서 comment 메소드를 호출할 수 있습니다. 테이블 주석은 현재 MySQL과 PostgreSQL에서만 지원됩니다:

Schema::create('calculations', function (Blueprint $table) {
    $table->comment('Business calculations');

    // ...
});

6.2 테이블 업데이트[ | ]

기존 테이블을 업데이트하려면 Schema 파사드에서 table 메소드를 사용할 수 있습니다. create 메소드와 마찬가지로 table 메소드는 테이블 이름과 Blueprint 인스턴스를 받는 클로저를 인수로 받습니다. 이 Blueprint 인스턴스를 사용하여 테이블에 컬럼 또는 인덱스를 추가할 수 있습니다:

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

이 예제에서는 'users' 테이블에 'votes'라는 정수형 컬럼을 추가하고 있습니다.

6.3 테이블 이름변경 / 삭제[ | ]

기존 데이터베이스 테이블의 이름을 변경하려면 rename 메소드를 사용하세요:

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

기존 테이블을 삭제하려면 drop 또는 dropIfExists 메소드를 사용할 수 있습니다:

Schema::drop('users');
 
Schema::dropIfExists('users');
외래 키가 있는 테이블 이름변경

테이블 이름을 변경하기 전에, 마이그레이션 파일에서 외래 키 제약 조건에 명시적인 이름을 지정했는지 확인해야 합니다. 그렇지 않으면 Laravel이 관례에 따라 이름을 지정하여 외래 키 제약조건 이름이 기존 테이블 이름을 참조하게 됩니다.

7 컬럼[ | ]

7.1 컬럼 생성[ | ]

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');
});

7.2 사용가능한 컬럼 타입[ | ]

스키마 빌더 블루프린트는 데이터베이스 테이블에 추가할 수 있는 다양한 컬럼 유형에 해당하는 여러 메소드를 제공합니다. 각 메소드는 아래 표에 나와 있습니다.

  • bigIncrements
  • bigInteger
  • binary
  • boolean
  • char
  • dateTimeTz
  • dateTime
  • date
  • decimal
  • double
  • enum
  • float
  • foreignId
  • foreignIdFor
  • foreignUlid
  • foreignUuid
  • geography
  • geometry
  • id
  • increments
  • integer
  • ipAddress
  • json
  • jsonb
  • longText
  • macAddress
  • mediumIncrements
  • mediumInteger
  • mediumText
  • morphs
  • nullableMorphs
  • nullableTimestamps
  • nullableUlidMorphs
  • nullableUuidMorphs
  • rememberToken
  • set
  • smallIncrements
  • smallInteger
  • softDeletesTz
  • softDeletes
  • string
  • text
  • timeTz
  • time
  • timestampTz
  • timestamp
  • timestampsTz
  • timestamps
  • tinyIncrements
  • tinyInteger
  • tinyText
  • unsignedBigInteger
  • unsignedInteger
  • unsignedMediumInteger
  • unsignedSmallInteger
  • unsignedTinyInteger
  • ulidMorphs
  • uuidMorphs
  • ulid
  • uuid
  • year
bigIncrements()

bigIncrements 메소드는 자동-증가하는 UNSIGNED BIGINT(주키) 컬럼을 생성합니다:

$table->bigIncrements('id');
bigInteger()

bigInteger 메소드는 BIGINT 컬럼을 생성합니다:

$table->bigInteger('votes');
binary()

binary 메소드는 BLOB 컬럼을 생성합니다:

$table->binary('photo');

MySQL, MariaDB, 또는 SQL Server를 사용할 때 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']);
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(Spatial Reference System Identifier)를 가진 GEOGRAPHY 컬럼을 생성합니다:

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

공간 유형에 대한 지원은 데이터베이스 드라이버에 따라 다릅니다. PostgreSQL 데이터베이스를 사용하는 경우 geography 메소드를 사용하기 전에 PostGIS 확장을 설치해야 합니다.

geometry()

geometry 메소드는 주어진 공간 유형과 SRID(Spatial Reference System Identifier)를 가진 GEOMETRY 컬럼을 생성합니다:

$table->geometry('positions', subtype: 'point', srid: 0);
공간 유형에 대한 지원은 데이터베이스 드라이버에 따라 다릅니다. PostgreSQL 데이터베이스를 사용하는 경우 <code>geometry</code> 메소드를 사용하기 전에 PostGIS 확장을 설치해야 합니다.

;<code>id()</code>
<code>id</code> 메소드는 <code>bigIncrements</code> 메소드의 별칭입니다. 기본적으로 <code>id</code> 컬럼을 생성하지만, 컬럼 이름을 전달하여 다른 이름을 할당할  있습니다:

<syntaxhighlight lang='php'>
$table->id();
increments()

increments 메소드는 자동 증가하는 UNSIGNED INTEGER(주키) 컬럼을 생성합니다:

$table->increments('id');
integer()

integer 메소드는 INTEGER 컬럼을 생성합니다:

$table->integer('votes');
ipAddress()

ipAddress 메소드는 VARCHAR 컬럼을 생성합니다:

$table->ipAddress('visitor');
PostgreSQL을 사용하는 경우 INET 컬럼이 생성됩니다.

;<code>json()</code>
<code>json</code> 메소드는 <code>[[JSON]]</code> 컬럼을 생성합니다:

<syntaxhighlight lang='php'>
$table->json('options');
jsonb()

jsonb 메소드는 JSONB 컬럼을 생성합니다:

$table->jsonb('options');
longText()

longText 메소드는 LONGTEXT 컬럼을 생성합니다:

$table->longText('description');
MySQL 또는 MariaDB를 사용하는 경우 이진 문자 세트를 컬럼에 적용하여 <code>[[LONGBLOB]]</code> 컬럼을 생성할  있습니다:

<syntaxhighlight lang='php'>
$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를 사용하는 경우 이진 문자 세트를 컬럼에 적용하여 <code>[[MEDIUMBLOB]]</code> 컬럼을 생성할  있습니다:

<syntaxhighlight lang='php'>
$table->mediumText('data')->charset('binary'); // MEDIUMBLOB
morphs()

morphs 메소드는 {column}_id 컬럼과 {column}_type VARCHAR 컬럼을 추가하는 편의 메소드입니다. {column}_id의 컬럼 유형은 모델 키 유형에 따라 UNSIGNED BIGINT, CHAR(36) 또는 CHAR(26)가 됩니다. 다음 예제에서는 taggable_idtaggable_type 컬럼이 생성됩니다:

$table->morphs('taggable');
nullableTimestamps()

nullableTimestamps 메소드는 timestamps 메소드의 별칭입니다:

$table->nullableTimestamps(precision: 0);
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 메소드는 선택적 소수 초 정밀도가 있는 nullable deleted_at TIMESTAMP(시간대 포함) 컬럼을 추가합니다. 이 컬럼은 Eloquent의 "소프트 삭제" 기능에 필요한 deleted_at 타임스탬프를 저장하는 데 사용됩니다:

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

softDeletes 메소드는 선택적 소수 초 정밀도가 있는 nullable 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 컬럼을 생성할 수 있습니다:

$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 컬럼을 생성할 수 있습니다:

$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');
year()

year 메소드는 YEAR 컬럼을 생성합니다:

$table->year('birth_year');

7.3 컬럼 수정자[ | ]

테이블에 컬럼을 추가할 때 사용할 수 있는 여러 컬럼 "수정자"가 있습니다. 예를 들어, 컬럼을 "nullable"로 만들기 위해 nullable 메소드를 사용할 수 있습니다:

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

다음 표는 사용가능한 모든 컬럼 수정자를 포함하고 있습니다. 인덱스 수정자는 포함되어 있지 않습니다:

수정자 설명
->after('column') 다른 컬럼 뒤에 컬럼을 배치합니다 (MySQL).
->autoIncrement() INTEGER 컬럼을 자동증가(주키)로 설정합니다.
->charset('utf8mb4') 컬럼의 문자 세트를 지정합니다 (MySQL).
->collation('utf8mb4_unicode_ci') 컬레이션을 지정합니다.
->comment('my comment') 컬럼에 주석을 추가합니다 (MySQL / PostgreSQL).
->default($value) 컬럼의 기본 값을 지정합니다.
->first() 컬럼을 테이블의 처음에 배치합니다 (MySQL).
->from($integer) 자동 증가 필드의 시작 값을 설정합니다 (MySQL / PostgreSQL).
->invisible() SELECT * 쿼리에서 컬럼을 "보이지 않게" 만듭니다 (MySQL).
->nullable($value = true) NULL 값을 컬럼에 삽입할 수 있도록 허용합니다.
->storedAs($expression) 저장된 생성된 컬럼을 만듭니다 (MySQL / PostgreSQL / SQLite).
->unsigned() INTEGER 컬럼을 UNSIGNED로 설정합니다 (MySQL).
->useCurrent() TIMESTAMP 컬럼을 기본 값으로 CURRENT_TIMESTAMP로 설정합니다.
->useCurrentOnUpdate() TIMESTAMP 컬럼을 레코드가 업데이트될 때 CURRENT_TIMESTAMP로 설정합니다 (MySQL).
->virtualAs($expression) 가상 생성된 컬럼을 만듭니다 (MySQL / SQLite).
->generatedAs($expression) 지정된 시퀀스 옵션으로 identity 컬럼을 만듭니다 (PostgreSQL).
->always() identity 컬럼에 대한 시퀀스 값의 입력 우선순위를 정의합니다 (PostgreSQL).
기본 표현식

기본 수정자는 값을 또는 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

기본 표현식의 지원 여부는 데이터베이스 드라이버, 데이터베이스 버전, 필드 유형에 따라 다릅니다. 데이터베이스의 문서를 참조하십시오.

컬럼 순서

MySQL 데이터베이스를 사용할 때, 스키마에서 기존 컬럼 뒤에 컬럼을 추가할 수 있습니다:

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

7.4 컬럼 수정[ | ]

change 메소드를 사용하면 기존 컬럼의 유형과 속성을 수정할 수 있습니다. 예를 들어, string 컬럼의 크기를 늘리고 싶을 수 있습니다. 이를 위해 name 컬럼의 크기를 25에서 50으로 늘리는 방법을 살펴보겠습니다. 이를 수행하기 위해 새로운 컬럼의 상태를 정의하고, 그 다음에 change 메소드를 호출합니다:

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

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

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

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

// 인덱스 추가...
$table->bigIncrements('id')->primary()->change();

// 인덱스 삭제...
$table->char('postal_code', 10)->unique(false)->change();

7.5 컬럼 이름변경[ | ]

컬럼 이름을 변경하려면 스키마 빌더에서 제공하는 renameColumn 메소드를 사용할 수 있습니다:

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

여기서 'users'는 테이블 이름이고, 'from'은 현재 컬럼 이름이며 'to'는 변경하고자 하는 새 컬럼 이름입니다.

7.6 컬럼 삭제[ | ]

컬럼을 삭제하려면 스키마 빌더의 dropColumn 메소드를 사용할 수 있습니다:

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

여러 컬럼을 한 번에 삭제하려면 dropColumn 메소드에 컬럼 이름의 배열을 전달합니다:

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

이렇게 하면 'users' 테이블에서 '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() 메소드의 별칭입니다.

이러한 메서드를 사용하면 해당 기능에 대해 명확하고 간결하게 열을 삭제할 수 있습니다.

8 인덱스[ | ]

8.1 인덱스 생성[ | ]

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');

여러 컬럼에 대한 복합(조합) 인덱스를 생성하려면 배열 형태로 컬럼 이름들을 index 메소드에 전달할 수도 있습니다:

$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'); 전체 텍스트 인덱스 추가 (MySQL / PostgreSQL)
$table->fullText('body')->language('english'); 특정 언어의 전체 텍스트 인덱스 추가 (PostgreSQL)
$table->spatialIndex('location'); 공간 인덱스 추가 (SQLite 제외)

이러한 메소드들을 사용하여 Laravel의 스키마 빌더를 통해 다양한 유형의 인덱스를 쉽게 생성할 수 있습니다.

8.2 인덱스 이름변경[ | ]

인덱스 이름을 변경하려면 스키마 빌더 블루프린트에서 제공하는 renameIndex 메소드를 사용할 수 있습니다. 이 메소드는 첫 번째 인자로 현재 인덱스 이름을, 두 번째 인자로 원하는 새 이름을 받습니다:

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

여기서 'from'은 현재 사용 중인 인덱스의 이름이고, 'to'는 변경하려는 새 인덱스의 이름입니다.

8.3 인덱스 삭제[ | ]

인덱스를 삭제하기 위해서는 Laravel에서 해당 인덱스의 이름을 명시해야 합니다. 기본적으로 Laravel은 테이블 이름, 인덱스된 열의 이름, 그리고 인덱스 유형에 따라 자동으로 인덱스 이름을 할당합니다. 몇 가지 예시를 살펴보겠습니다:

명령어 설명
$table->dropPrimary('users_id_primary'); "users" 테이블에서 주키(primary key)를 삭제합니다.
$table->dropUnique('users_email_unique'); "users" 테이블에서 고유(unique) 인덱스를 삭제합니다.
$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']); // 'geo_state_index' 인덱스를 삭제합니다.
});

8.4 외래키 제약조건[ | ]

Laravel은 데이터베이스 수준에서 참조 무결성을 강제할 수 있는 외래키 제약조건을 생성하는 기능을 제공합니다. 예를 들어, posts 테이블에 user_id 컬럼을 정의하고 이 컬럼이 users 테이블의 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'
    );
});

"on delete"와 "on update" 속성에 대한 원하는 작업을 명시할 수도 있습니다:

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

또한, 이 작업들을 다음과 같이 다른 표현으로 지정할 수도 있습니다:

메소드 설명
$table->cascadeOnUpdate(); 업데이트가 발생하면 연쇄적(cascade)으로 업데이트합니다.
$table->restrictOnUpdate(); 업데이트가 제한됩니다.
$table->noActionOnUpdate(); 업데이트 시 아무 작업도 수행하지 않습니다.
$table->cascadeOnDelete(); 삭제가 발생하면 연쇄적으로 삭제합니다.
$table->restrictOnDelete(); 삭제가 제한됩니다.
$table->nullOnDelete(); 삭제 시 외래키 값을 null로 설정합니다.

추가적인 컬럼 수정자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 () {
    // 이 클로저 내에서 제약조건이 비활성화됩니다...
});

Warning

SQLite에서는 기본적으로 외래키 제약조건이 비활성화되어 있습니다. SQLite를 사용할 때는 마이그레이션에서 외래키 지원을 활성화하기 전에 데이터베이스 설정에서 외래키 지원을 활성화해야 합니다. 또한, SQLite는 테이블 생성 시에만 외래키를 지원하며 테이블 변경 시에는 지원하지 않습니다.

9 이벤트[ | ]

편의를 위해 각각의 마이그레이션 작업은 각각의 이벤트를 트리거합니다. 다음은 모두 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 기존 데이터베이스 스키마 덤프가 로드되었습니다.

10 같이 보기[ | ]

문서 댓글 ({{ doc_comments.length }})
{{ comment.name }} {{ comment.created | snstime }}