> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Migraciones de base de datos

> Explicamos cómo versionar el esquema de la base de datos usando las migraciones de Laravel.

## ¿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`.

```shell theme={null}
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 theme={null}
<?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étodo                              | Descripció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.

```php theme={null}
$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.

```shell theme={null}
php artisan migrate
```

Para ver el estado de las ejecutadas y pendientes, usa `migrate:status`.

```shell theme={null}
php artisan migrate:status
```

<Warning>
  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.
</Warning>

## Rollback

Para deshacer el último lote de migraciones, usa `migrate:rollback`.

```shell theme={null}
php artisan migrate:rollback
```

Para revertir un número concreto de pasos, usa la opción `--step`.

```shell theme={null}
# 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`.

```shell theme={null}
php artisan migrate:refresh
```

<Info>
  `migrate:refresh` recrea todas las tablas, así que los datos existentes se pierden.
  Es útil para reiniciar la base de datos durante el desarrollo.
</Info>

## 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

```shell theme={null}
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 theme={null}
<?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

```shell theme={null}
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.

```shell theme={null}
php artisan make:migration add_excerpt_to_posts_table
```

```php theme={null}
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');
    });
}
```

<Tip>
  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.
</Tip>

## Eventos de migración

Cada operación de migración dispara [eventos](/es/events). Todos ellos extienden `Illuminate\Database\Events\MigrationEvent`.

| Clase                                            | Descripción                                                 |
| ------------------------------------------------ | ----------------------------------------------------------- |
| `Illuminate\Database\Events\DatabaseRefreshed`   | Al completarse el comando `migrate:refresh`                 |
| `Illuminate\Database\Events\MigrationsStarted`   | Justo antes de ejecutarse un lote de migraciones            |
| `Illuminate\Database\Events\MigrationsEnded`     | Al completarse el lote de migraciones                       |
| `Illuminate\Database\Events\MigrationStarted`    | Justo antes de ejecutarse una única migración               |
| `Illuminate\Database\Events\MigrationEnded`      | Al completarse una única migración                          |
| `Illuminate\Database\Events\NoPendingMigrations` | Cuando el comando detecta que no hay migraciones pendientes |
| `Illuminate\Database\Events\SchemaDumped`        | Al completarse el volcado del esquema                       |
| `Illuminate\Database\Events\SchemaLoaded`        | Al cargarse un volcado de esquema existente                 |

Por ejemplo, puedes escuchar el evento `MigrationsEnded` para limpiar la caché tras completar las migraciones.

```php theme={null}
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

<Card title="Seeding de base de datos" icon="seedling" href="/es/seeding">
  Aprende a insertar datos de muestra en las tablas creadas mediante migraciones.
</Card>

<Card title="Introducción a Eloquent" icon="database" href="/es/eloquent">
  Aprende a manipular con Eloquent ORM las tablas creadas por las migraciones.
</Card>


## Related topics

- [Pruebas de base de datos](/es/database-testing.md)
- [Seeding de base de datos](/es/seeding.md)
- [Configuración de la base de datos](/es/database.md)
- [Instalación](/es/installation.md)
- [Desarrollar paquetes con Testbench Workbench](/es/advanced/package-workbench.md)
