verbanent/eloquent-binary-uuid

Ordered binary UUID in Laravel / Eloquent based on UUID version 1

v1.8.1 2023-02-14 20:12 UTC

This package is auto-updated.

Last update: 2024-10-15 00:00:38 UTC


README

Quality Gate Status Downloads StyleCI CodeFactor Maintainability Rating Lines of Code Coverage Packagist PHP Version Support Packagist License

Based on articles about the optimization of UUID storage in databases, I decided to write a simple library that allows this in my projects. I based on the information available here:
https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/
https://www.percona.com/community-blog/2018/10/12/generating-identifiers-auto_increment-sequence/

The package currently only supports MySQL.

Installation

Please install the package via Composer:

composer require verbanent/eloquent-binary-uuid

Migration

Your model will use an ordered binary UUID, if you prepare a migration:

Schema::create('table_name', function (Blueprint $table) {
    $table->uuid('id');
});

Or if you want to use a custom column name for the primary key:

Schema::create('table_name', function (Blueprint $table) {
    $table->uuid('uuid');
    $table->primary('uuid');
});

Using UUID in models

All what you have to do, is use a new trait in models with UUID as a primary key:

use Illuminate\Database\Eloquent\Model;
use Verbanent\Uuid\Traits\BinaryUuidSupportableTrait;

class Book extends Model
{
    use BinaryUuidSupportableTrait;
}

The above example works for the column id. If you use custom name for UUID column, you need to define it:

use Illuminate\Database\Eloquent\Model;
use Verbanent\Uuid\Traits\BinaryUuidSupportableTrait;

class Book extends Model
{
    use BinaryUuidSupportableTrait;

    public $uuidColumn = 'uuid';
}

Abstract model for model with UUID

For your convenience you can extend your model with AbstractModel:

use Verbanent\Uuid\AbstractModel;

class Lang extends AbstractModel
{
    //
}

The above example works for the column id. If you use custom name for UUID column, you need to define it:

use Verbanent\Uuid\AbstractModel;

class Lang extends AbstractModel
{
    public $uuidColumn = 'uuid';
    protected $primaryKey = 'uuid';
    protected $fillable = ['uuid'];
}

Foreign binary UUID

If you would like to use UUID as a foreign key, use another trait and set $uuidable property for this model:

use Verbanent\Uuid\AbstractModel;
use Verbanent\Uuid\Traits\ForeignBinaryUuidSupportableTrait;

class LangTranslation extends AbstractModel
{
    use ForeignBinaryUuidSupportableTrait;

    private $uuidable = [
        'lang',
        'one_lang_bucket',
    ];
}

Getting a string form of UUID

The library is kept as simple as possible, so if you want to get a string form of UUID, just use a method:

$book = new \App\Book;
$book->save();
dd($book->uuid());
// Output: "11e947f9-a1bd-f844-88d8-6030d483c5fe"

or use a property, if you need a binary value:

# If you use the default primary key:
dd($book->id);
// Output: b"\x11éGù¡½øDˆØ`0ÔƒÅþ"

# If you use `uuid` as a primary key:
dd($book->uuid);
// Output: b"\x11éGù¡½øDˆØ`0ÔƒÅþ"

Finding by primary UUID

For primary keys finding rows is simple and always return a model:

$lang = Lang::find('11e947f9-a1bd-f844-88d8-6030d483c5fe');
dd($lang->uuid());
// Output: "11e947f9-a1bd-f844-88d8-6030d483c5fe"

Finding by foreign UUID

For foreign keys finding rows requires a column name and returns collection of model:

$langTranslation = LangTranslation::findByUuid('lang', '11e947f9-a1bd-f844-88d8-6030d483c5fe');
dd($langTranslation[0]->uuid(), $langTranslation[1]->uuid(), $langTranslation[2]->uuid());
// Output: "11e94805-b94c-68e0-8720-6030d483c5fe"
//         "11e94805-b955-4e2e-b089-6030d483c5fe"
//         "11e94805-b957-af02-8bf8-6030d483c5fe"

Getting a foreign UUID string

You can print string form of your foreign UUID keys:

$translation = LangTranslation::findByUuid('lang', '11e947f9-a1bd-f844-88d8-6030d483c5fe')->first();
dd($translation->foreignUuid('lang'));
// Output: "11e947f9-a1bd-f844-88d8-6030d483c5fe"

Because trying to have access to the property directly will print binary form of UUID:

dd($translation->lang);
// Output: b"\x11éGù¡½øDˆØ`0ÔƒÅþ"

Unit tests

Run this command if you want to check unit tests:

./vendor/bin/phpunit

Or if you want to check code coverage:

phpdbg -qrr vendor/bin/phpunit --coverage-html coverage tests