verbanent / eloquent-binary-uuid
Ordered binary UUID in Laravel / Eloquent based on UUID version 1
Installs: 6 342
Dependents: 0
Suggesters: 0
Security: 0
Stars: 3
Watchers: 2
Forks: 0
Open Issues: 0
Requires
- php: ^7.3|^8
- ramsey/uuid: ^3.8|^4
Requires (Dev)
- laravel/framework: ^6.20.26|^7|^8|^9|^10
- mockery/mockery: ^1
- phpunit/phpunit: ^9
README
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