Tratamiento de índices y claves al escribir migraciones en Laravel

  • Por
Cómo trabajar con claves, primarias, foráneas, así como índices al escribir las migraciones para definición de la base de datos en Laravel.

Seguimos con el tema de las migraciones en Laravel 5, profundizando acerca de los índices y la definición de claves en el código de las migraciones. Hay varios métodos y mecanismos que debemos de conocer para poder completar nuestros conocimientos para poder escribir migraciones.

Ya sabemos que los índices nos sirven a la hora de definir el esquema de la base de datos, permitiendo que el sistema gestor nos ayude optimizando las tablas y mejorando la velocidad de acceso a los datos, o permitiendo asuntos como que no se repitan los valores en una columna. Hay varios tipos de índices y claves que nos imaginamos que llegados a este punto conoces de antemano, así que vamos directamente a ver cómo trabajar con estos elementos en las migraciones.

Claves primarias

Los tipos de índices más comunes son los que se crean cuando se definen las claves primarias. En Laravel las claves primarias se definen automáticamente sobre los campos definidos como "increments". Este es un detalle que ocurre sin que tengamos que intervenir o especificar nada en las migraciones, no obstante, si no tenemos un campo autoincremental, se puede definir la clave de otra forma.

Schema::create('facturas', function (Blueprint $table) {
    $table->increments('id');
    $table->date('fecha');
});

Esta tabla tendrá como clave primaria el campo "id". Pero si al campo le hubiésemos llamado "id_factura" por ejemplo, también sería definida como clave primaria por el hecho de haber sido definido con "increments".

Nota: Existe un método alternativo para crear campos auto-increment, pero en este caso con posibilidad de llegar a valores de enteros muy grandes.

$table->bigIncrements('id');

Si queremos definir como clave primaria otro campo, que no sea un incremental, podemos realizarlo con el método primary().

Tendríamos dos maneras de hacer esto, encadenando el método primary() a la definición del campo.

$table->char('codigo', 25)->primary();

O definiendo el primary() una vez el campo está creado, en instrucciones diferentes.

$table->char('codigo', 25);
$table->primary('codigo');

Por último, podemos también crear claves primarias con una reunión de campos, simplemente indicando los campos sobre los que se genera el índice en un array que se enviará al método primary().

$table->char('area', 25);
$table->char('bloque', 2);
$table->primary(['area', 'bloque']);

Claves foráneas

En la realización de migraciones mediante Laravel existe también la posibilidad de especificar claves foráneas (foreign key), que se usarán para asegurar la integridad referencial de los datos.

Por ejemplo, podemos tener la clave id_cliente en la tabla de factura, que corresponde con el campo id de la tabla clientes. Entonces podemos definir la clave de esta manera:

$table->integer('id_cliente')->unsigned();
$table->foreign('id_cliente')->references('id')->on('clientes');

Aquí hay dos detalles que merece la pena remarcar. Primero, al construir el campo id_cliente, de tipo integer, le hemos indicado el modificador unsigned(). Es porque los campos de identificador son siempre sin signo, así que la columna id_cliente, para hacerla corresponder con el id de la tabla clientes, debe ser también unsigned. El otro detalle es en la llamada al método foreign(), observar como se encadenan una serie de métodos, para decirle que referencia al "id" que hay en la tabla "clientes". Creo que el código es suficientemente auto-explicativo.

Nota: Para poder hacer una referencia en una foreign key a otro campo en otra tabla, tal campo en esa tabla debe de existir. Osea, para que funcione el ejemplo anterior de migración debería haber una tabla "clientes" con un campo "id".

Aquí hay otro asunto interesante, los "delete cascade", que trataremos de manera práctica más adelante, pero no queremos desaprovechar la oportunidad de comentarlos. Como se puede saber sirve para borrar elementos relacionados en claves foráneas cuando se produce un delete. Simplemente se encadena una llamada a un método adicional onDelete('cascade'):

$table->foreign('id_cliente')->references('id')->on('clientes')->onDelete('cascade');

Escribir otros índices en las migraciones

Existe la posibilidad de crear otros índices, ya no relacionados con claves de una tabla, pero que nos permitan realizar búsquedas optimizadas o controlar los duplicados.

Los índices básicos se crean con el método index(). Por ejemplo, en la tabla de facturas queremos hacer consultas por fecha y queremos crear un índice en ese campo.

$table->date('fecha')->index();

Los índices únicos se crean con el método unique(). Por ejemplo en la tabla de clientes, el email podría ser único.

$table->string('email', 200)->unique();

Estos dos métodos también pueden invocarse una vez creado el campo en la tabla. Por ejemplo:

$table->date('fecha');
$table->index('fecha');

Eliminar índices creados

Podemos querer eliminar índices creados con anterioridad, para deshacer una migración en la que creamos el índice (cuando definimos el método down() del rollback) o bien para quitar un índice que ya no necesitamos en la base de datos.

Los cuatro métodos para eliminar índices, para los 4 tipos de índices que hemos visto, son:

  • dropIndex('indice') elimina un índice básico
  • dropUnique('indice') elimina un índice único
  • dropPrimary('indice') elimina una clave primaria
  • dropForeign('indice') elimina una clave foránea

Cualquiera de estos métodos recibe un único parámetro, que es el nombre del índice que se debe eliminar. Ese nombre lo crea automáticamente Laravel al ejecutarse el sistema de migracines y está compuesto por varios segmentos separados por un guión bajo:

  • Nombre de la tabla
  • Campo o columna sobre la que se crea el índice
  • Tipo de índice

Nosotros podemos componer el nombre del índice fácilmente juntando esos datos, algo como "facturas_fecha_index", "clientes_email_unique" o "facturas_id_cliente_foreign". Pero si no damos con el nombre exacto, podemos ver los nombres asignados a los índices directamente con un programa de acceso a bases de datos, tipo PhpMyAdmin, MySQL Workbench o Sequel Pro. Asimismo, lo podemos hacer desde el terminal, conectando con el intérprete de MySQL o nuestro motor escogido y lanzando esta sentencia SQL:

show index from nombre_de_tabla;

De momento eso es todo, con lo que sabes deberías poder crear todo tipo de migraciones. Te recomendamos buscar en la documentación oficial otras informaciones o referencias.

Autor

Carlos Ruiz Ruso

Consultor tecnológico para el desarrollo de proyectos online especializado en WordPress y el framework Laravel.

Compartir