Migraciones

1. Introducción

En proyectos reales, En el desarrollo de una aplicación, suele ocurrir que el esquema de base de datos cambia continuamente: se añaden campos, se refactorizan tablas, se crean relaciones, se aplican restricciones, etc. Hacer estos cambios a mano en phpMyAdmin (o en un SQL suelto) suele romper la trazabilidad, dificulta el trabajo en equipo y hace frágiles los despliegues entre entornos (local, preproducción, producción).

Es cierto que una vez desarrollada la aplicación, la base de datos sigue siendo un elemento crítico, pero menos frecuentes, presentando pocos cambios (es algo ideal…).

Laravel resuelve esto con migraciones: una forma versionada, repetible y automatizable de definir la estructura de la base de datos como código. En un equipo, todos comparten el mismo histórico de cambios, y el proyecto puede “levantar” la base de datos desde cero de forma consistente.

A su vez, laravel nos va a ofrecer la posibilidad de poblar de forma automatizada las tablas de la base de datos, constituyendo un entorno ideal para poder probar nuestra aplicación según la vamos desarrollando.

Estos datos serán datos fictícios o datos faker, y constituirán un entorno ideal para poder probar nuestra aplicación.


Objetivos

Qué veremos aquí


  • - Identificar qué problema resuelven las migraciones en un proyecto web profesional.
  • - Crear migraciones desde consola y localizar su archivo en el proyecto.
  • - Aplicar, deshacer y rehacer migraciones usando comandos de Artisan.
  • - Modelar columnas, índices y claves foráneas con el Schema Builder.
  • - Diseñar migraciones seguras (reversibles) y mantenibles en equipo.
  • - Detectar errores comunes en migraciones y aplicar buenas prácticas.

Migración

Es un fichero PHP (una clase) que permite crear/modificar/eliminar tablas en nuestra aplicación (podríamos decir que es el principal uso que le vamos a dar).

Además, permite mantener un versionado del esquema de la base de datos, lo que hace posible replicarlo exactamente en cualquier entorno (desarrollo, pruebas o producción, o cuando se clone el proyecto) simplemente ejecutando un comando.

Schema Builder

Schema Builder es la API de Laravel que permite definir tablas, columnas, índices y restricciones de forma expresiva, sin necesidad de escribir SQL manualmente.

Se utiliza dentro de las migraciones para estructurar la base de datos mediante métodos como create, table, string, integer, foreignId, etc.

Cuando hablamos aquí de API, estamos indicando un conjunto de métodos públicos disponibles en Schema y Blueprint, que podemos usar directamente. Son intuitivos y no necesitamos conocer su implementación. Es una librería de utilidades que tenemos disponibles:

## Ejemplos de métodos disponibles
use Illuminate\Support\Facades\Schema;

    Schema::create()
    Schema::table()
    $table->string()
    $table->integer()
    $table->foreignId()
    $table->timestamps()
    $table->unique()
Blueprint

Es el objeto que representa el diseño de una tabla durante la ejecución de una migración.

Su uso es implícito, ya que Laravel lo inyecta, cuando usamos los métodos dentro de Schema::create() o Schema::table(). Permite permite definir columnas, índices y claves foráneas utilizando una sintaxis fluida y orientada a objetos.

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('student', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->string('address');
            $table->timestamps();
        });
up() / down()
up() / down()
  • up(): Crea elementos: contiene las instrucciones para aplicar el cambio (crear tabla, añadir columnas, modificar estructura).
  • down(): Elimina: revierte los cambios realizados en up() (eliminar tabla, eliminar columnas, etc.).

Esto permite que los cambios en la base de datos sean reversibles y controlados.

  public function up(): void
    {
        Schema::create('student', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            });
    }
  public function down(): void
    {
        Schema::dropIfExists('student');
   }
migrate / rollback / refresh

migrate / rollback / refresh son operaciones habituales ejecutadas desde Artisan:

  • migrate: aplica las migraciones pendientes y crea las tablas definidas.
  • rollback: revierte el último lote de migraciones ejecutadas.
  • refresh: revierte todas las migraciones y las vuelve a ejecutar desde cero (muy útil en desarrollo).

Estas operaciones permiten gestionar la evolución del esquema de la base de datos de forma controlada.


Las migraciones

Las migraciones se guardan en: database/migrations

Laravel registra qué migraciones se han ejecutado en una tabla interna llamada migrations

Aunque es algo que no vamos a usar, es interesante saber que el proyecto guarda el histórico de cambios en Git y la base de datos guarda el “estado aplicado” en la tabla migrations. Podríamos deshacer los 3 ultimos cambios por ejemplo o el último o deshacer todo, como veremos a continuación


Acciones concretas

  1. Crear migración (nombra el cambio)
  2. Programar up() y down() (reversible)
  3. Ejecutar migrate (aplica en tu DB local)
  4. Subir cambios a Git
  5. En otro entorno (otro compañero / servidor), ejecutar migrate y obtener el mismo esquema

1.- Crear migraciones desde consola (Artisan)
    php artisan make:migration create_students_table

2.- Modificar una tabla existente

php artisan make:migration add_phone_to_students_table

3.-Crear migración y modelo a la vez (opcional, pero común) Aunque no hemos visto qué es un modelo, lo vamos a necesitar para interactuar con la base de datos desde nuestra aplicación Lo estudiamos en el tema de modelos

php artisan make:model Student -m

Convención de nombres :

  • create_x_table para crear
  • add_y_to_x_table para añadir
  • remove_y_from_x_table para eliminar
  • update_x_table o change_y_in_x_table para cambios complejos

Estructura de una migración

Una migración típica tiene esta forma:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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('students', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamps();
        });
    }

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

Puntos importantes :

  • Schema::create define una tabla desde cero
  • Blueprint $table define columnas, índices, etc.
  • down() revierte de forma segura con dropIfExists
  • up() Ejecuta la migración creando los elementos especificados (crear o modificar)

Ejecutar migraciones

Las principales acciones que vamos a realizar con las migraciones son las siguientes

Ejecutar todas las migraciones pendientes

php artisan migrate

Consultar el estado de las migraciones

1
php artisan migrate:status

Deshacer última acción (última migración ejecutado)

1
php artisan migrate:rollback

Deshacer las últimas N migraciones ejecutadas

1
php artisan migrate:rollback --step=3

Reiniciar el esquema completo (rollback total + migrate)

1
php artisan migrate:refresh

Borrar todas las tablas y volverlo a crear (muy usado en desarrollo) Esta acción la haremos con mucha frecuencia

1
php artisan migrate:fresh

Borrar todo y además ejecutar los seeders

1
php artisan migrate:fresh --seed
Criterio profesional :

  • fresh es ideal para desarrollo local cuando puedes perder datos
  • en producción casi siempre se usa migrate (nunca fresh)

4.6. Tipos de columnas más habituales (Laravel 12)

Identificadores y timestamps
  • id(): BIGINT autoincremental
  • timestamps(): created_at / updated_at
  • softDeletes(): deleted_at para borrado lógico
1
2
3
4
5
Schema::create('students', function (Blueprint $table) {
    $table->id();
    $table->timestamps();
    $table->softDeletes();
});
Strings, texto y números
  • string: VARCHAR(255) por defecto
  • text: TEXT
  • integer, bigInteger
  • decimal(8,2) para importes
  • boolean
1
2
3
4
5
6
7
Schema::table('students', function (Blueprint $table) {
    $table->string('name', 120);
    $table->text('notes')->nullable();
    $table->integer('age')->nullable();
    $table->decimal('tuition_fee', 8, 2)->default(0);
    $table->boolean('active')->default(true);
});
Fechas
  • date, time, dateTime
  • timestamp
1
2
3
4
Schema::table('students', function (Blueprint $table) {
    $table->date('birth_date')->nullable();
    $table->dateTime('last_login_at')->nullable();
});

Índices y restricciones: performance + integridad

El tema de índices es muy importante y lo tenemos que tener muy claro

Índices y únicos
  • index() acelera búsquedas
  • unique() evita duplicados
1
2
3
4
Schema::table('students', function (Blueprint $table) {
    $table->string('dni', 12)->unique();
    $table->string('city')->index();
});

Regla práctica :

  • index: para columnas que se filtran mucho (where)
  • unique: para “identificadores” (email, dni, código, etc.)

Resumen
  • Las migraciones nos van a permitir crear la base de datos y gestionarla
  • Permiten versionar el esquema de base de datos como código.
  • Se crean con make:migration y se aplican con migrate.
  • up() aplica cambios; down() los revierte: migraciones reversibles son más profesionales.
  • Schema Builder define columnas, índices y claves foráneas de forma expresiva.
  • Evita editar migraciones ya ejecutadas: crea nuevas migraciones para corregir/refactorizar.
  • En producción, normalmente se usa migrate (no fresh).

referencias

1 - Seeders en Laravel

Inserción de datos iniciales o de prueba mediante Seeders en Laravel.

🏭 Factory vs 🌱 Seeder (Esquema conceptual)

🎯 Idea sencilla

  • Factory → fabrica datos
  • Seeder → inserta datos en la base de datos

🏗 Esquema como “flujo de fabricación”

[ Factory ]
     ↓
  Genera objetos con datos falsos
     ↓
[ Seeder ]
     ↓
 Inserta esos datos en la tabla
     ↓
[ Base de Datos ]

🏭 Factory

Factory

Es una clase que define cómo se construyen datos de prueba para un modelo.

No inserta nada en la base de datos.
Solo define qué valores tendrá cada campo.

Ejemplo mental:

  • name → nombre aleatorio
  • email → email único
  • age → número aleatorio

Es como una máquina que fabrica registros.

📁 Ubicación: database/factories/StudentFactory.php

Ejemplo básico:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class StudentFactory extends Factory
{
public function definition(): array
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'age' => fake()->numberBetween(18, 30),
];
}
}

🌱 Seeder

Seeder

Es una clase que se encarga de insertar datos en la base de datos.

Puede usar una Factory para generar los datos automáticamente.

Es como la persona que coge lo fabricado y lo planta en la tabla.

📁 Ubicación: database/seeders/StudentSeeder.php

Ejemplo básico:

1
2
3
4
5
6
7
class StudentSeeder extends Seeder
{
public function run(): void
{
Student::factory()->count(10)->create();
}
}

🧠 Diferencia clara para alumnos

Concepto Qué hace Inserta en BD
Factory Define cómo se crean los datos ❌ No
Seeder Ejecuta la inserción ✅ Sí

🔄 Relación práctica real

Cuando ejecutamos:

1
php artisan db:seed

El flujo real es:

Seeder → usa Factory → genera datos → los guarda en la tabla


🎓 Frase clave para recordar

Factory fabrica los datos.
Seeder los siembra en la base de datos.


2 -

title: “Factories y Seeders en Laravel” date: date: 2023-04-08T18:21:47+02:00 draft: true weight: 20 icon: fa-solid fa-seedling description: “Generación y carga de datos de prueba mediante Factories y Seeders en Laravel.”

Qué son las migraciones


Una migración en Laravel
crear y modificar la estructura de la base de datos
agregar, modificar y/o eliminar tablas y columnas

Ubicacion de las migraciones


img.png