Может войдёшь?
Черновики Написать статью Профиль

Laravel и ULID

В прошлой статье мы разобрались как в Laravel работать с UUID. Но он не решает всех проблем распределенных систем. Один из новых подходов к генерации уникальных идентификаторов это ULID — Universally Unique Lexicographically Sortable Identifier (универсальный уникальный лексографически сортируемый идентификатор).

Сравнение UUID и ULID

Во многих случаях использование UUID неоптимально:

  • Это не самый эффективный способ кодирования 128-битной случайности
  • UUID v1/v2 непрактичен во многих средах, так как требует доступа к уникальному стабильному MAC-адресу
  • UUID v3/v5 требует уникального начального числа и генерирует случайно распределенные идентификаторы, которые могут вызвать фрагментацию во многих структурах данных
  • UUID v4 не предоставляет никакой другой информации, кроме случайности, которая может вызвать фрагментацию во многих структурах данных

Вместо этого ULID предлагает:

  • 128-битная совместимость с UUID
  • 1.21e+24 уникальных ключей в миллисекунду
  • Лексикографическая сортировка (т.е. в алфавитном порядке)
  • Канонически кодируется как 26-символьная строка, в отличие от 36-символьного UUID
  • Использует Crockford Base32 для лучшей эффективности и читаемости (5 бит на символ). Исключены буквы I, L, O, чтобы не путать с цифрами. И буква U, чтобы случайно не сгенерировались непристойность
  • Регистронезависимый
  • Без специальных символов (безопасный URL)
  • Точность метки времени до миллисекунды
  • Да просто выглядит эстетичнее, чем UUID :)

Более подробно можно узнать в спецификации ULID

Пример ULID:

    ulid();
    // 01d85pp1982gf6ktvfhq7w78fb
    01d85pp198   2gf6ktvfhq7w78fb
    Timestamp       Randomness
     48bits           80bits

Когда нужен ULID в качестве первичного ключа?

В распределенных системах, когда нужна уверенность, что у идентификаторов не будет коллизий. В высоконагруженной системы, когда автоинкрементный ключ не вариант. Когда нужна репликация без геморроя (в отличии от int). Когда не хотите показывать пользователю, что получаете информацию об идентификаторе (например: example.com/user/3)

Использование ULID в Laravel

Ставим пакет

    composer require rorecek/laravel-ulid:^2.0.0

Создаём модель

    php artisan make:model Product -mcr

Исправляем в миграции модели строку $table->increments(‘id’); на $table->char(‘id’, 26)->primary();

Если связанная модель использует ULID, то тип колонки должен это отображать

    Schema::create('products', function (Blueprint $table) {
      $table->char('id', 26)->primary();
      ....
      // связанная модель
      $table->char('category_id', 26);
      $table->foreign('category_id')->references('id')->on('categories');
      ....
      $table->timestamps();
    });

В модели укажите использование трейта HasUlid и выставьте флаг incrementing на false.

    use Illuminate\Database\Eloquent\Model;
    use Rorecek\Ulid\HasUlid;
    class Product extends Model
    {
      use HasUlid;
      ....
      /**
      * Indicates if the IDs are auto-incrementing.
      *
      * @var bool
      */
      public $incrementing = false;
      ....
    }

Теперь, когда вы создаете новый экземпляр модели, ULID генерируется автоматически.

    $item = Product::create();
    echo $item->id;
    // 01d85pp1982gf6ktvfhq7w78fb

Как вы считаете, полезен ли этот материал? Да Нет

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.