Saltar al contenido principal

¿Qué son las migraciones?

Las migraciones son como un sistema de control de versiones para la base de datos. Permiten que un equipo comparta y gestione la definición del esquema de la aplicación. Seguramente hayas vivido la situación de tener que decir a otro miembro del equipo: “Añade manualmente esta columna a tu base de datos local tras hacer pull”. Las migraciones resuelven ese problema. Los archivos de migración se guardan en el directorio database/migrations. Cada nombre de archivo incluye una marca de tiempo que Laravel usa para determinar el orden de ejecución.

Creación de un archivo de migración

Crea un nuevo archivo de migración con el comando Artisan make:migration.
php artisan make:migration create_posts_table
A partir del nombre, Laravel deduce el nombre de la tabla y genera el stub adecuado. Con create_posts_table te crea de partida el código para crear la tabla posts.

Estructura de una migración

Una clase de migración tiene dos métodos: up y down.
  • up: añade tablas, columnas o índices a la base de datos.
  • down: revierte lo que hace up. Se llama al hacer rollback.
<?php

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

return new class extends Migration
{
    /**
     * Ejecuta la migración
     */
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('body');
            $table->boolean('published')->default(false);
            $table->timestamps();
        });
    }

    /**
     * Revierte la migración
     */
    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};

Principales métodos para definir columnas

La clase Blueprint ofrece muchos tipos de columna.
MétodoDescripción
$table->id()Clave primaria auto-incremental (alias de bigIncrements('id'))
$table->string('name')Columna equivalente a VARCHAR (255 por defecto)
$table->text('body')Columna TEXT
$table->integer('count')Columna INTEGER
$table->boolean('active')Guarda booleano como TINYINT
$table->timestamp('published_at')Columna TIMESTAMP
$table->timestamps()Añade created_at y updated_at juntos
$table->softDeletes()Añade la columna deleted_at para soft delete
$table->foreignId('user_id')Columna BIGINT UNSIGNED para clave foránea

Modificadores de columna

Puedes encadenar modificadores en la definición de la columna.
$table->string('email')->unique();
$table->string('name')->nullable();
$table->integer('votes')->default(0);
$table->string('title')->after('id'); // Se coloca después de la columna indicada

Ejecución de migraciones

Con migrate ejecutas todas las migraciones pendientes.
php artisan migrate
Para ver el estado de las ejecutadas y pendientes, usa migrate:status.
php artisan migrate:status
En producción, al ejecutar migraciones aparece un prompt de confirmación. Para ejecutarlo sin confirmación usa --force, pero ten precaución porque algunas operaciones destruyen datos.

Rollback

Para deshacer el último lote de migraciones, usa migrate:rollback.
php artisan migrate:rollback
Para revertir un número concreto de pasos, usa la opción --step.
# Revertir las 5 migraciones más recientes
php artisan migrate:rollback --step=5
Para revertir todas las migraciones y volver a ejecutarlas, usa migrate:refresh.
php artisan migrate:refresh
migrate:refresh recrea todas las tablas, así que los datos existentes se pierden. Es útil para reiniciar la base de datos durante el desarrollo.

Ejemplo práctico: crear la tabla posts

Repasemos el flujo completo con una tabla posts para gestionar publicaciones de blog.

1. Generar el archivo de migración

php artisan make:migration create_posts_table

2. Editar la migración

Abre y edita database/migrations/xxxx_xx_xx_xxxxxx_create_posts_table.php.
<?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('posts', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->string('title');
            $table->text('body');
            $table->boolean('published')->default(false);
            $table->timestamp('published_at')->nullable();
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};

3. Ejecutar la migración

php artisan migrate
Después de ejecutarla, la tabla posts se creará en la base de datos.

4. Añadir columnas más tarde

Para añadir nuevas columnas a una tabla existente, no edites la migración original: crea una nueva.
php artisan make:migration add_excerpt_to_posts_table
public function up(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->string('excerpt')->nullable()->after('title');
    });
}

public function down(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->dropColumn('excerpt');
    });
}
Evita editar directamente archivos de migración ya ejecutados. Rompes la coherencia con el resto del equipo o con producción. Los cambios se añaden siempre como nuevas migraciones.

Eventos de migración

Cada operación de migración dispara eventos. Todos ellos extienden Illuminate\Database\Events\MigrationEvent.
ClaseDescripción
Illuminate\Database\Events\DatabaseRefreshedAl completarse el comando migrate:refresh
Illuminate\Database\Events\MigrationsStartedJusto antes de ejecutarse un lote de migraciones
Illuminate\Database\Events\MigrationsEndedAl completarse el lote de migraciones
Illuminate\Database\Events\MigrationStartedJusto antes de ejecutarse una única migración
Illuminate\Database\Events\MigrationEndedAl completarse una única migración
Illuminate\Database\Events\NoPendingMigrationsCuando el comando detecta que no hay migraciones pendientes
Illuminate\Database\Events\SchemaDumpedAl completarse el volcado del esquema
Illuminate\Database\Events\SchemaLoadedAl cargarse un volcado de esquema existente
Por ejemplo, puedes escuchar el evento MigrationsEnded para limpiar la caché tras completar las migraciones.
use Illuminate\Database\Events\MigrationsEnded;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Event;

Event::listen(MigrationsEnded::class, function () {
    Cache::flush();
});

Próximos pasos

Seeding de base de datos

Aprende a insertar datos de muestra en las tablas creadas mediante migraciones.

Introducción a Eloquent

Aprende a manipular con Eloquent ORM las tablas creadas por las migraciones.
Última modificación el 13 de julio de 2026