UUID это универсальный уникальный идентификатор. 16-байтный (128-битный) номер, используемый для уникальной идентификации какого-либо объекта без общего центра координации. То есть мы самостоятельно генерируем UUID и уверены, что полученный идентификатор уникален. Общее количество уникальных ключей UUID составляет 2128 = 25616 или около 3,4 x 1038. Генерируя 1 триллион ключей каждую наносекунду, перебрать все возможные значения удастся лишь за 10 миллиардов лет. В шестнадцатеричной системе счисления UUID выглядит как:
9675e665-1923-4c6f-97c0-259b191fab24
Я не буду вдаваться в подробности плюсов и минусов UUID по сравнению с обычным автоматическим инкрементным идентификатором, про это есть отдельные статьи. Но я расскажу вам как можно использовать UUID в вашей Laravel.
Первым шагом использования UUID в вашей базе данных это настройка столбца идентификатора. По умолчанию в каждой миграция Laravel автоматически создается столбец $table->primary(‘id’);.
Использовать UUIDs так же просто, как обновить миграцию. Добавляем метод ->uuid(), доступный прямо из «коробки». Например миграция для сущности Post:
Schema::create('posts', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('title');
$table->text('body');
$table->timestamps();
});
Обратите внимание на строку: $table->uuid(‘id’)->primary();. Мы используем метод uuid() вместо обычного increments().
Если вы запустите php artisan migrate и попытаетесь создать новую запись, через фабрику или вручную, то получите ошибку, утверждающую, что столбец id не может быть null.
При использовании метода primary() в миграциях Laravel понимает, что это автоинкрементный столбец, и создает его таким. Но, поскольку мы перешли на использование UUID, нам нужно создавать ID самостоятельно.
Раз мы работает с Laravel, то скорей всего используем и Eloquent для взаимодействия с базой данных.
Eloquent имеет так называемую Событийная модель (Model Events). В общей сложности он запускает 11 событий в разных сценариях:
Если вы хотите узнать о Событиях больше, то ознакомьтесь с документацией.
Вернемся к созданию UUID. Давайте посмотрим, как может выглядеть ваша модель Post:
class Post extends Model
{
protected $guarded = [];
protected static function boot()
{
parent::boot();
static::creating(function ($post) {
$post->{$post->getKeyName()} = (string) Str::uuid();
});
}
public function getIncrementing()
{
return false;
}
public function getKeyType()
{
return 'string';
}
}
Модель имеет 3 метода. В методе boot мы можем подключиться к нашей модели и прослушивать любые события Eloquent. Метод getIncrementing используется Eloquent, если идентификаторы в таблице инкрементны. Помните, мы используем UUID, поэтому устанавливаем false на автоинкремент. А метод getKeyType просто указывает, что идентификаторы в таблице должны храниться в виде строк.
В нашем методе boot мы ожидаем события creating. Оно запускается непосредственно перед тем, как запись сохраняется в базе данных. Мы подключаемся к этому событию и используем метод uuid(), предоставленный классом Str в Laravel.
Раньше, для генерации UUID необходимо было устанавливать дополнительный пакет через Composer, а сейчас это есть прямо в Laravel.
Обычно я делаю отдельный трейт (trait) под названием UsesUuid, где я храню логику, описанную выше. Это позволяет не повторять код для каждой модели, где нужно использовать UUID:
<?php
namespace App\Models\Concerns;
use Illuminate\Support\Str;
trait UsesUuid
{
protected static function bootUsesUuid()
{
static::creating(function ($model) {
if (! $model->getKey()) {
$model->{$model->getKeyName()} = (string) Str::uuid();
}
});
}
public function getIncrementing()
{
return false;
}
public function getKeyType()
{
return 'string';
}
}
Обратите внимание, что всё обобщенно и не привязано к отдельной модели.
Теперь в любой модели, вы можете просто использовать трейт UsesUuid следующим образом:
class Post extends Model
{
use App\Models\Concerns\UsesUuid;
protected $guarded = [];
}
Вот и все. Всего за несколько простых шагов вы получили UUID для Laravel.
Автор: Wilbur Powery
Перевод: Demiurge Ash