arety_
arety_

Reputation: 2203

Laravel ID primary auto increment alternative

In my application most of the IDs (user_id, classroom_id, post_id, assessment_id and so on) are publicly available which means that they are either in the URL or the name of a directory. For safety reasons I‘d like to have 10 character random IDs for every table instead of the auto incremented ones.

I could use a timestamp but this isn‘t really unique and with random numbers added it would get much longer (for example I would have to add 4 random numbers to handle up to 10.000 DB inserts to a table per second... purely hypothetically it's not scaleable).

Now I’d prefer to create a 10 character random ID, this would give me 10 billion possible ID combinations. So the chance to generate a duplicate is very small and the length is also acceptable.

use Keygen;

$id = Keygen::numeric(10)->generate();

Do you think that my thoughts make sense? And does anyone know if using 10 character primary IDs would affect my DB performance negatively? Thanks!

Upvotes: 2

Views: 4375

Answers (3)

petersowah
petersowah

Reputation: 788

You can use UUIDs. I suggest you use the default Laravel string helper method to generate UUIDs. See below on how to achieve this.

use Illuminate\Support\Str;

$uuid = Str::uuid()->toString(); //this generates a v4 UUID.

In your migration, you can specify a uuid column like this;

**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{ 
    Schema::create('users', function (Blueprint $table) {
        $table->uuid('id')->primary(); //uuid field set to PK
    });
}

In your models, say User.php, set the following properties.

protected $primaryKey = 'id';

public $incrementing = false;

protected $keyType = 'string';

I do suggest, you keep an autoincrement column in your tables to help you determine the number of records without writing any queries(This is optional). eg. say such column is rowId, you can hide that from your response by adding it to the array of hidden properties on the model. Eg.

protected $hidden = [
    'password', 'remember_token', 'rowId'
];

Hope this helps out.

Upvotes: 1

Rezrazi
Rezrazi

Reputation: 895

I can suggest three packages for ID generation.

  1. Webpatser's Laravel UUID package
    Allows the generation of UUIDs for your models, fairly simple to setup and use. This type of ids is unpredictable and might be considered safer, but cannot be sorted in your database. Github
  2. Vinkla's Laravel Hashids package
    Keep your current ids and get a hash that can be decrypted to obfuscate the ids publicly. Github
  3. Hafael's Laraflake package
    Twitter snowflake like id generation, good performance and better features, ids can be sorted. Github

You can take a look at all three available packages, and choose one, or you can make a DIY solution inspired from those.

Upvotes: 6

Sjoerd Loeve
Sjoerd Loeve

Reputation: 231

You better use UUID instead.

What database type do you use? Most of the database types support the UUID type and can generate them automatic so you don't have to generate them yourself.

Check out: https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_uuid

Upvotes: 1

Related Questions