adamthehutt/laravel-unique-bigint-ids

This package is abandoned and no longer maintained. No replacement package was suggested.

This allows for the generation of sequential IDs that can be created before inserting into the database and are virtually (but not totally) guaranteed to be globally unique for the app. Additional benefits come from generating IDs before DB persistence, which streamlines code for, e.g., attaching re

v0.7.1 2021-02-13 01:45 UTC

README

This allows for the generation of sequential IDs that can be created before inserting into the database and are virtually (but not totally) guaranteed to be globally unique for the app.

Installation

Install using composer:

composer require adamthehutt/laravel-unique-bigint-ids

Then publish the configuration:

php artisan vendor:publish

To use this package with a model, just use the contract and the trait:

use AdamTheHutt\LaravelUniqueBigintIds\Contracts\IdGenerator;
use AdamTheHutt\LaravelUniqueBigintIds\GeneratesIdsTrait;

class MyModel extends Model implements IdGenerator
{
    use GeneratesIdsTrait;

DB Migrations

If you are going to use the trait with existing models, then you'll need to create and run migrations to make sure the relevant primary and foreign keys are all unsigned 64-bit integers without auto-increment, e.g.,

$table->bigInteger("id")->unsigned()->primary();
$table->bigInteger("foreign_id")->unsigned();

What's wrong with UUIDs?

Nothing! UUIDs are great and I use them all the time. But they solve a different category of problems and come with non-trivial challenges when used as primary keys. The IDs generated by this package are plain old integers (albeit very large ones). They are not globally unique like UUIDs. But they are virtually guaranteed to be unique within the scope of your Laravel application.

What's wrong with AUTO_INCREMENT?

Conventional, auto-incremented primary keys are fine if that's your cup of tea. But there are practical benefits from generating an ID in the application upon model creation, rather than waiting until it has been persisted in the database.

Better handling of complex relations

Complex real-world entities often need multiple related eloquent models to be fully represented. This can be awkward with standard auto-incremented IDs since you can't properly associate or attach related models until after the "main" one has been saved to the database. When IDs are assigned on model creation, you can fully associate all related models as they are built and then safely save them to the database without worrying about "last second" assignment of foreign keys.

Fear not sharded databases

If your application uses database shards you don't need to worry about different databases duplicating each other's primary keys.

One fewer roundtrip

There's a tiny performance boost from avoiding the additional roundtrip to the database that comes from calling LAST_INSERT_ID().

Configuration / Strategies

The package provides multiple methods for generating the IDs:

  • "timestamp" - The default method is to use the 16 digits of a microsecond timestamp and append the last 2 digits of the current process ID. This should work 99.9% of the time.

  • "uuid_short" - You can edit the config file to set "uuid_short" as the generation strategy. This will call the UUID_SHORT() mysql function in your database and use the returned value.

  • "redis" - You can edit the config file to set "redis" as the generation strategy. In this case, the Laravel Redis facade will be used to increment and retrieve an incremented ID. If the key is not present, it will be initialized using the timestamp strategy.

Javascript Gotchas

Javascript barfs on integers larger than 2^53. When serializing models to JSON it's therefore important to cast large 64-bit integers to strings. This package handles that for you, but that only affects the models that use it. If you have other models that don't use this package's trait but have foreign key relationships with those that do, then you'll need to address this when serializing them to JSON.

Alternatively, you can set the UNIQUE_BIGINT_ID_JAVASCRIPT_SAFE environment variable to true. This will cause the library to use slightly reduced precision when generating timestamp-based IDs: 14 significant digits instead of 16. This should not increase the likelihood of collisions, but could result in a very slight performance hit, since it becomes impossible to generate more than 2 IDs in the same 1/10000th of second.