Cómo usar uuid como llave primaria en Laravel

usar uuid como llave primaria en Laravel

Si, si lo sé, seguro estas pensando…

Otra vez lo mismo

En parte si porque este articulo en realidad es para dar respuesta a la pregunta que planteo nuestro amigo Manuel Dautt (ver comentarios) en el articulo pasado.

Así que me pareció buena idea hacer un articulo al respecto y que este esta opción para que se puedan comparar y tu mi estimado amigo puedas decidir que opción es mas conveniente para ti. Ademas el uso de uuid tiene otras ventajas.

¿Qué es UUID?

Uuid (Unique universal identifier) es en pocas palabras un numero de 128bit que dependiendo del mecanismo empleado para generarlo garantiza que sera único o al menos diferente con una probabilidad muy baja de que se repita al menos en los próximos 1000 anos!!.

Y si estas pensando que te puede servir para evitar ids predecibles… estas en lo correcto!

Pero no solo es la única ventaja.

  • Son únicos en todas las tablas, bases de datos y servidores lo que es muy útil cuando requerimos hacer migraciones de base de datos.
  • Los uuid se generan en cualquier lugar, es decir que puede o no estar centralizada su creación y es independiente de la base de datos, esto es muy útil ya que podemos conocer el siguiente uuid sin tener que acceder a la base de datos (Siempre que nosotros controlemos su creación).

Pero sean cuidadosos este cambio puede impactar en el rendimiento a la hora de hacer búsquedas, existen otras opciones para hacer uso de uuids empleando otra columna de tu base de datos.

Dicho esto, comencemos instalando un paquete que nos ayudara a generar los uuid.

Instalando Ramsey uuid

Para la instalación solo requieres ejecutar composer

$ composer require ramsey/uuid

Esto solo es necesario para versiones de Laravel menores a la 5.5. A partir de la versión 5.6 solo tienes que usar el helper Str::uuid.

Si buscas algo mas al estilo de laravel tambien puedes usar Laravel Uuid.

Modificando migraciones

En todas las migraciones de los modelos que queremos que usen uuid como llave primaria, solo tenemos que cambiar la siguiente linea:

$table->increments('id');

Por esta:

$table->uuid('id')->primary();

Listo con ese cambio ya tenemos un id de tipo uuid, como ejemplo voy a mostrarte como queda la migración del modelo User que viene por defecto en las instalaciones de Laravel.

Como puedes notar a sido muy sencillo modificar la migración.

Cambiar modelos

Nuestro siguiente paso es decirle a nuestros modelos que ya no usaremos un valor que se incrementa como id, pero esto, es algo que se soluciona de forma muy sencilla en Laravel;

solo tienes que establecer la propiedad $incrementing a false y la propiedad $keyType al valor ‘string’.

Esto queda de la siguiente forma en nuestro modelo User (recuerda que es nuestro ejemplo!)

Muy bien, ya esta listo, pero para insertar un id ahora lo tenemos que hacer de forma manual:

$user->id = Ramsey\Uuid\Uuid::uuid4();

Imagina hacer esto para todos lo modelos!!,  Es algo no muy conveniente así que para solucionar esto podemos hacer uso de los eventos de Eloquent.

Creando Trait.

Así que usaremos… lo sé, lo sé

Que te puedo decir

 

Pero prometo que es solo por el ejemplo y como todo no es la única alternativa.

Bien nuestro Trait va a quedar de la siguiente forma:

Con este Trait ya no sera necesario que nosotros asignemos los uuid de forma manual.

nuestro siguiente y ultimo paso sera agregar el Trait a nuestro modelo de ejemplo

use Notifiable, AutoGenerateUuid;

Ahora si, prueba a crear un nuevo usuario y notaras que se guarda con su uuid correspondiente

$user = User::create($data);

También puedes buscar un modelo por su uuid y todo funcionara de forma correcta.

$user = User::findOrFail('6e791bc7-500f-4fc6-8877-50629087ea7f');

Y en general puedes hacer cualquier operación que normalmente hacías.

Para finalizar

Hemos visto que implementar el uso de uuid es en realidad sencillo y al igual que hashids nos ayuda a eliminar las rutas predecible y ademas es muy útil en las situaciones en las que tenemos bases de datos distribuidas en otros servidores asegurando que no tendremos colisiones en nuestros ids.

Como mencione tambien el uso de un trait no es la única opción para implemenar el uso de uuid mediante eventos de Eloquent, otra alternativa es crear una clase base de la cual hereden los modelos que van a usar uuid.

Pero en lo personal prefiero ir por otra opción y es usar un observer ya que es una solución muy limpia y hacer que todos tus modelos lo usen es realmente sencillo, les dejo esta excelente explicación de Jose Fonseca para usar uuid usando un observer, empleando otra columna de la base de datos todo probado mediante TDD.

Espero que este articulo te guste y si te fue de utilidad deja tu comentario, y si tienes dudas no te quedes con ellas! me encuentras en el slack!

 

Comparte este artículo

Entra en la discusión y deja tu comentario

Veces