Skip to content
This repository has been archived by the owner on Jun 19, 2022. It is now read-only.

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.

License

Notifications You must be signed in to change notification settings

adamthehutt/laravel-unique-bigint-ids

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Laravel Unique 64-bit Integer IDs

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.

About

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.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages